diff --git a/install-plugins.sh b/install-plugins.sh index 7edd35d..36efd82 100644 --- a/install-plugins.sh +++ b/install-plugins.sh @@ -62,7 +62,10 @@ if [ -n "$CFG_SNAPSHOT" ]; then done trap restore_curated_configs EXIT else - warn "Config guard disabled (mktemp failed) — CLAUDE.md/settings may drift" + err "Config guard could not be created (mktemp failed) — refusing to run" \ + "unguarded: CLAUDE.md/.claude/settings.json/settings.json could be" \ + "silently rewritten by the installer. Fix mktemp/TMPDIR and retry." + exit 1 fi # Read pinned version from plugins.lock.json diff --git a/lib/tests/curated-config-guard.test.sh b/lib/tests/curated-config-guard.test.sh index bff7133..60e888c 100644 --- a/lib/tests/curated-config-guard.test.sh +++ b/lib/tests/curated-config-guard.test.sh @@ -46,7 +46,33 @@ cmp -s "$REPO/.claude/settings.json" "$EXPECT/.claude/settings.json" check T2-untouched-local-settings-unchanged "$?" 0 cmp -s "$REPO/settings.json" "$EXPECT/settings.json" check T3-untouched-settings-unchanged "$?" 0 -[ ! -d "$CFG_SNAPSHOT" ] -check T4-snapshot-dir-removed "$?" 0 +if [ -d "$CFG_SNAPSHOT" ]; then r4=present; else r4=gone; fi +check T4-snapshot-dir-removed "$r4" gone + +# --- T5: mktemp failure -> fail-closed (install-plugins.sh, the header block +# that builds CFG_SNAPSHOT) — refuses to run unguarded instead of warning and +# continuing. Extracted with a WIDER range than the SUT above: this logic +# lives in the top-level if/else, outside restore_curated_configs(). +SUT2="$(mktemp)" +awk '/^GUARDED_CONFIGS=/,/^fi$/' "$INSTALL_SH" > "$SUT2" +ERR5="$(mktemp)" +( + # shellcheck disable=SC2329 # invoked indirectly by the sourced snippet below + mktemp() { return 1; } # force the header's CFG_SNAPSHOT creation to fail + # shellcheck disable=SC2329 + err() { echo "ERR: $*" >&2; } + # shellcheck disable=SC2329 + warn() { echo "WARN: $*" >&2; } + # shellcheck disable=SC2329 + info() { :; } + REPO="$(command mktemp -d)" + # shellcheck source=/dev/null + source "$SUT2" +) >/dev/null 2>"$ERR5" +rc5=$? +check T5-mktemp-failure-aborts "$rc5" 1 +if grep -qi 'mktemp failed' "$ERR5"; then r5msg=yes; else r5msg=no; fi +check T5-mktemp-failure-loud "$r5msg" yes +rm -f "$ERR5" "$SUT2" printf 'PASS=%s FAIL=%s\n' "$pass" "$fail"; [ "$fail" -eq 0 ]