check-setup.sh: false "permissions 644 (should be 600)" warning on Windows Git Bash (includes fix)
Summary
On Windows Git Bash / MSYS2 / Cygwin, the /watch SessionStart hook (hooks/scripts/check-setup.sh) prints a permissions warning for ~/.config/watch/.env on every session start, and the chmod 600 it suggests can never clear it.
This is the same problem previously raised in #170 (withdrawn by its author as a courtesy — "filed in error on my side, don't want to take up maintainer time" — not fixed) and is related to #47. The fix is still not upstream in v0.2.0, so I'm re-filing with a concrete, verified patch.
Environment
- watch 0.2.0 (installed copy byte-identical to upstream v0.2.0)
- Windows 11, Git Bash / MSYS2 (
uname -s->MINGW64_NT-10.0-26200) /cmountednoacl(the Git for Windows default):C: on /c type ntfs (binary,noacl,posix=0,user,noumount,auto)
What happens
Every session start prints:
/watch: WARNING — /c/Users/<user>/.config/watch/.env has permissions 644 (should be 600).
Fix: chmod 600 /c/Users/<user>/.config/watch/.envRunning the suggested command changes nothing, so the warning reappears on every session.
Root cause
hooks/scripts/check-setup.sh reads the mode with stat -c '%a'. Under a noacl mount, MSYS2 does not read the NTFS ACL — it synthesises a POSIX mode, and chmod is a no-op:
stat -c '%a' before chmod 600 : 644
stat -c '%a' after chmod 600 : 644Meanwhile the real NTFS ACL on the file is already owner-only (e.g. LAPTOP-XXXX\<user>:(F) after stripping inheritance with icacls). So the file was never loose, the warning is false, and the remedy it recommends does nothing. A check that reads a synthesised value cannot support a claim about permissions — on these mounts it is guaranteed to be either a false warning or false reassurance.
Proposed fix
Skip the POSIX-mode check on MSYS/Cygwin, where the value is fabricated; keep it unchanged on Linux/macOS. Real access control on Windows is governed by NTFS ACLs (via icacls), not POSIX mode.
# Warn if the secrets file has loose permissions.
-if [[ -f "$CONFIG_FILE" ]]; then
- perms=$(stat -c '%a' "$CONFIG_FILE" 2>/dev/null || stat -f '%Lp' "$CONFIG_FILE" 2>/dev/null || echo "")
- if [[ -n "$perms" && "$perms" != "600" && "$perms" != "400" ]]; then
- echo "/watch: WARNING — $CONFIG_FILE has permissions $perms (should be 600)."
- echo " Fix: chmod 600 $CONFIG_FILE"
- fi
-fi
+# Skip on Windows Git Bash / Cygwin: those mounts are typically `noacl`, so
+# `stat` always reports 644 for a writable file regardless of the real Windows
+# ACL, producing a permanent false warning. Access there is governed by NTFS
+# ACLs (set via icacls), not POSIX mode.
+case "$(uname -s 2>/dev/null || echo)" in
+ MINGW*|MSYS*|CYGWIN*) ;;
+ *)
+ if [[ -f "$CONFIG_FILE" ]]; then
+ perms=$(stat -c '%a' "$CONFIG_FILE" 2>/dev/null || stat -f '%Lp' "$CONFIG_FILE" 2>/dev/null || echo "")
+ if [[ -n "$perms" && "$perms" != "600" && "$perms" != "400" ]]; then
+ echo "/watch: WARNING — $CONFIG_FILE has permissions $perms (should be 600)."
+ echo " Fix: chmod 600 $CONFIG_FILE"
+ fi
+ fi
+ ;;
+esacVerified locally: with this patch the hook runs clean (exit 0, no warning) on Git Bash, and the check is unchanged on Linux/macOS. Happy to open a PR if that's preferred.
Source: bradautomates/claude-video