skills/golem-powers/shell-hardening/SKILL.md
Security checklist for bash scripts — injection prevention, set -euo pipefail, printf safety, path quoting. Apply before committing any shell script. Triggers on: 'shell-hardening', 'bash script security', 'harden shell'. NOT for: general shell scripting help (just write code), non-bash languages, runtime debugging.
npx skillsauth add etanhey/golems shell-hardeningInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Apply to EVERY bash script before committing. The March 26 overnight sprint found security issues in every orchestrator worker PR (D-R1 through D-R6). Common patterns: JSON injection via printf, shell metacharacter bypass, unquoted paths.
#!/usr/bin/env bash
set -euo pipefail
set -e — exit on errorset -u — error on undefined variablesset -o pipefail — pipe failures propagateprintf with format strings to construct JSON — use jqecho "$var" in command construction — use arrayseval or bash -c "$string" with user input# WRONG — JSON injection
printf '{"name": "%s"}' "$user_input"
# RIGHT — jq handles escaping
jq -n --arg name "$user_input" '{"name": $name}'
# WRONG — metacharacter injection
cmd="git commit -m $message"
eval "$cmd"
# RIGHT — array construction
cmd=(git commit -m "$message")
"${cmd[@]}"
"$file_path" not $file_pathrealpath or readlink -f to resolve symlinks..mktemp not hardcoded /tmp pathstrap 'rm -f "$tmpfile"' EXIT for cleanupif ! command; then handle_error; fi|| true only when failure is genuinely acceptableecho "ERROR: ..." >&2set -o pipefail)awk '{exit}', head -1, grep -m1) SIGPIPE-kills the producer → exit 141, often masked as success in naive scriptsstatus, path, etc.) as variable names# WRONG — producer gets SIGPIPE under pipefail
some_generator | awk '/pattern/{print; exit}'
# RIGHT — buffer then consume
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
some_generator > "$tmp"
awk '/pattern/{print; exit}' "$tmp"
See /mac-systems mechanical truths #3–#4 for environment context.
shellcheck script.sh before committing# Run on any script (covers section 6 — ShellCheck):
shellcheck --severity=warning script.sh && echo "CLEAN" || echo "ISSUES FOUND"
Note: ShellCheck covers syntax and common pitfalls but does NOT detect sections 1-5 (injection patterns, path traversal, temp file misuse). Those require manual review using the checklist above.
tools
The human-eval UX contract for Phoenix views: turn-by-turn scrollable replay (not a scorecard), hide-but-copyable IDs, collapsed thinking, identity chips, tool filters, tiny frozen starter datasets, mark-wrong-in-thread, mobile-first. Use when: building or reviewing ANY Phoenix/eval view, annotation UI, session replay, or human-grading surface. Triggers: phoenix view, eval UI, annotation view, session replay, human eval UX, grading interface. NOT for: Phoenix data pipelines/ingest (capture scripts have their own specs).
tools
macOS systems specialist — AppKit NSPanel architecture, launchd services, socket activation, MCP bridge resilience, syspolicyd, and high-frequency SwiftUI dashboards. Use when building menu-bar apps, LaunchAgents, debugging syspolicyd/Gatekeeper/TCC, resilient UDS/MCP bridges, or SwiftUI dashboards at 10Hz+.
development
Bulk LLM-judging protocol for fleet-dispatched verdict runs (KG cluster, eval harness). Use when: dispatching or running judge workers (J1/J2/RT), planning bulk-apply from verdict JSONL, or triaging evidence_degraded outputs. Triggers: judge fleet, bulk judge, R3 verdicts, kg-judge, RT gate, evidence_degraded. NOT for: single-item code review, Phoenix view UX (use phoenix-human-view), or non-judge eval pipelines.
development
Quiet-down protocol for sprint close: when the fleet wraps, delete ALL polling crons and monitors, send ONE final dashboard + ONE message, then go SILENT. Use when: fleet wraps, all workers done, overnight queue exhausted, sprint close, Etan asleep/away with nothing approved left. Triggers: fleet wrap, wrap the fleet, stand down, going quiet, sprint close. NOT for: mid-sprint monitoring (keep your loops), spawning a successor (use /session-handoff first).