Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .claude/hooks/no-ai-tells.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,43 @@ INPUT="$(cat)"
if ! command -v jq >/dev/null 2>&1; then exit 0; fi
if ! printf '%s' "$INPUT" | jq -e . >/dev/null 2>&1; then exit 0; fi

# Rust path: prefer agentcloseout-physics when available.
if command -v agentcloseout-physics >/dev/null 2>&1; then
RULES_DIR="${LLM_DARK_PATTERNS_RULES_DIR:-}"
if [ -z "$RULES_DIR" ]; then
for candidate in \
"$(dirname "$0")/../../agent-closeout-bench/rules/closeout" \
"/home/fer/Documents/agent-closeout-bench/rules/closeout" \
"${XDG_CONFIG_HOME:-$HOME/.config}/agentcloseout-physics/rules/closeout"; do
if [ -d "$candidate" ]; then RULES_DIR="$candidate"; break; fi
done
fi
if [ -n "$RULES_DIR" ] && [ -d "$RULES_DIR" ] && [ -f "$RULES_DIR/no_ai_tells.yaml" ]; then
TMP_INPUT="$(mktemp)"; printf '%s' "$INPUT" > "$TMP_INPUT"
VERDICT_JSON="$(agentcloseout-physics scan --category no_ai_tells --rules "$RULES_DIR" --input "$TMP_INPUT" 2>/dev/null || true)"
rm -f "$TMP_INPUT"
if [ -n "$VERDICT_JSON" ]; then
DECISION="$(printf '%s' "$VERDICT_JSON" | jq -r '.decision // empty' 2>/dev/null)"
if [ "$DECISION" = "block" ]; then
RULE="$(printf '%s' "$VERDICT_JSON" | jq -r '.matched_rules[0].rule_id // "no_ai_tells"' 2>/dev/null)"
EVIDENCE="$(printf '%s' "$VERDICT_JSON" | jq -r '.redacted_evidence[0] // ""' 2>/dev/null)"
echo "BLOCKED: AI tell — phrases that mark text as obviously LLM-generated." >&2
echo "Matched rule: $RULE" >&2
[ -n "$EVIDENCE" ] && echo "Evidence: $EVIDENCE" >&2
echo "" >&2
echo "Repair guidance:" >&2
echo "- Replace LLM-default phrases with plain language." >&2
echo "- If you mean 'discuss', say 'discuss', not 'delve into'." >&2
echo "- If you mean 'use', say 'use', not 'leverage'." >&2
exit 2
fi
if [ "$DECISION" = "pass" ]; then
exit 0
fi
fi
fi
fi

json_get() { printf '%s' "$INPUT" | jq -r "$1 // empty" 2>/dev/null || true; }
block() {
echo "BLOCKED: $1" >&2
Expand Down
36 changes: 36 additions & 0 deletions .claude/hooks/no-meta-commentary.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,42 @@ INPUT="$(cat)"
if ! command -v jq >/dev/null 2>&1; then exit 0; fi
if ! printf '%s' "$INPUT" | jq -e . >/dev/null 2>&1; then exit 0; fi

# Rust path: prefer agentcloseout-physics when available.
if command -v agentcloseout-physics >/dev/null 2>&1; then
RULES_DIR="${LLM_DARK_PATTERNS_RULES_DIR:-}"
if [ -z "$RULES_DIR" ]; then
for candidate in \
"$(dirname "$0")/../../agent-closeout-bench/rules/closeout" \
"/home/fer/Documents/agent-closeout-bench/rules/closeout" \
"${XDG_CONFIG_HOME:-$HOME/.config}/agentcloseout-physics/rules/closeout"; do
if [ -d "$candidate" ]; then RULES_DIR="$candidate"; break; fi
done
fi
if [ -n "$RULES_DIR" ] && [ -d "$RULES_DIR" ] && [ -f "$RULES_DIR/no_meta_commentary.yaml" ]; then
TMP_INPUT="$(mktemp)"; printf '%s' "$INPUT" > "$TMP_INPUT"
VERDICT_JSON="$(agentcloseout-physics scan --category no_meta_commentary --rules "$RULES_DIR" --input "$TMP_INPUT" 2>/dev/null || true)"
rm -f "$TMP_INPUT"
if [ -n "$VERDICT_JSON" ]; then
DECISION="$(printf '%s' "$VERDICT_JSON" | jq -r '.decision // empty' 2>/dev/null)"
if [ "$DECISION" = "block" ]; then
RULE="$(printf '%s' "$VERDICT_JSON" | jq -r '.matched_rules[0].rule_id // "no_meta_commentary"' 2>/dev/null)"
EVIDENCE="$(printf '%s' "$VERDICT_JSON" | jq -r '.redacted_evidence[0] // ""' 2>/dev/null)"
echo "BLOCKED: meta-commentary narrating thought instead of producing answer." >&2
echo "Matched rule: $RULE" >&2
[ -n "$EVIDENCE" ] && echo "Evidence: $EVIDENCE" >&2
echo "" >&2
echo "Repair guidance:" >&2
echo "- Drop the meta opener. Lead with the substantive answer." >&2
echo "- If reasoning needs to be shown, show it — don't announce it." >&2
exit 2
fi
if [ "$DECISION" = "pass" ]; then
exit 0
fi
fi
fi
fi

json_get() { printf '%s' "$INPUT" | jq -r "$1 // empty" 2>/dev/null || true; }
block() {
echo "BLOCKED: $1" >&2
Expand Down
36 changes: 36 additions & 0 deletions .claude/hooks/no-prompt-restate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,42 @@ INPUT="$(cat)"
if ! command -v jq >/dev/null 2>&1; then exit 0; fi
if ! printf '%s' "$INPUT" | jq -e . >/dev/null 2>&1; then exit 0; fi

# Rust path: prefer agentcloseout-physics when available.
if command -v agentcloseout-physics >/dev/null 2>&1; then
RULES_DIR="${LLM_DARK_PATTERNS_RULES_DIR:-}"
if [ -z "$RULES_DIR" ]; then
for candidate in \
"$(dirname "$0")/../../agent-closeout-bench/rules/closeout" \
"/home/fer/Documents/agent-closeout-bench/rules/closeout" \
"${XDG_CONFIG_HOME:-$HOME/.config}/agentcloseout-physics/rules/closeout"; do
if [ -d "$candidate" ]; then RULES_DIR="$candidate"; break; fi
done
fi
if [ -n "$RULES_DIR" ] && [ -d "$RULES_DIR" ] && [ -f "$RULES_DIR/no_prompt_restate.yaml" ]; then
TMP_INPUT="$(mktemp)"; printf '%s' "$INPUT" > "$TMP_INPUT"
VERDICT_JSON="$(agentcloseout-physics scan --category no_prompt_restate --rules "$RULES_DIR" --input "$TMP_INPUT" 2>/dev/null || true)"
rm -f "$TMP_INPUT"
if [ -n "$VERDICT_JSON" ]; then
DECISION="$(printf '%s' "$VERDICT_JSON" | jq -r '.decision // empty' 2>/dev/null)"
if [ "$DECISION" = "block" ]; then
RULE="$(printf '%s' "$VERDICT_JSON" | jq -r '.matched_rules[0].rule_id // "no_prompt_restate"' 2>/dev/null)"
EVIDENCE="$(printf '%s' "$VERDICT_JSON" | jq -r '.redacted_evidence[0] // ""' 2>/dev/null)"
echo "BLOCKED: prompt-restate preamble — operator does not need their request echoed back." >&2
echo "Matched rule: $RULE" >&2
[ -n "$EVIDENCE" ] && echo "Evidence: $EVIDENCE" >&2
echo "" >&2
echo "Repair guidance:" >&2
echo "- Drop the restate. Lead with the substantive answer." >&2
echo "- If clarification is needed, ask the specific question without prefacing 'I understand that...'." >&2
exit 2
fi
if [ "$DECISION" = "pass" ]; then
exit 0
fi
fi
fi
fi

json_get() { printf '%s' "$INPUT" | jq -r "$1 // empty" 2>/dev/null || true; }
block() {
echo "BLOCKED: $1" >&2
Expand Down