Files
boshu2__agentops/hooks/intent-echo.sh
T
Boden Fuller e8572ee8d9 feat(cli): backlog blitz wave 1 — bug fixes, test cleanup, skill templates (na-3re)
Wave 1 of na-3re (6 parallel issues, 0 file conflicts):

Issue 1 - Hook bugs:
- Merge double-jq in commit-review-gate.sh into single @tsv call
- Add session-aware dedup (PID-based) to intent-echo.sh

Issue 2 - Script bugs:
- Add pattern resolution logging to cherry-pick-wave.sh
- Improve coverage-ratchet.sh error handling for failed go test

Issue 3 - Run-ID classification:
- Fix rpiRunIDPattern: accept rpi-{8-12hex}, drop bare 8-hex false positives
- Update contract tests and serve tests for new pattern

Issue 4 - UTF-8 safety:
- Fix truncateGoal to use rune-safe slicing (was byte-slicing)
- Audit strings.Trim in goals/ — no misuse found

Issue 5 - Test cleanup:
- Strip 153 TestCov3_ prefixes across 15 files
- Merge fire_deep_test.go → fire_test.go
- Merge maturity_deep_test.go → maturity_test.go
- Fix malformed test names (lowercase after Test)

Issue 6 - Skill templates:
- Add test-fixture audit + go-build verification to /plan
- Add single-epic scope WARN to /crank
- Add footgun entries section to /post-mortem
2026-03-05 10:09:13 -05:00

92 lines
3.1 KiB
Bash
Executable File

#!/bin/bash
# intent-echo.sh - UserPromptSubmit hook: force intent confirmation for high-stakes operations
# Detects destructive/scoping keywords and injects echo protocol.
# Non-blocking (always exit 0). Injects reminder as additionalContext.
# Kill switches
[ "${AGENTOPS_HOOKS_DISABLED:-}" = "1" ] && exit 0
[ "${AGENTOPS_INTENT_ECHO_DISABLED:-}" = "1" ] && exit 0
# Read stdin
INPUT=$(cat)
# Extract prompt
if command -v jq >/dev/null 2>&1; then
PROMPT=$(echo "$INPUT" | jq -r '.prompt // ""' 2>/dev/null)
else
PROMPT=$(echo "$INPUT" | grep -o '"prompt"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"prompt"[[:space:]]*:[[:space:]]*"//;s/"$//')
fi
# No prompt → exit silently
[ -z "$PROMPT" ] || [ "$PROMPT" = "null" ] && exit 0
# Find repo root for state files
ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
STATE_DIR="$ROOT/.agents/ao"
mkdir -p "$STATE_DIR" 2>/dev/null
# Dedup: don't fire if already fired recently (10-min TTL) in same session
# Session boundary detection: PPID stored in flag file; different PPID = new session
DEDUP_FLAG="$STATE_DIR/.intent-echo-fired"
if [ -f "$DEDUP_FLAG" ]; then
STORED_PID=$(cat "$DEDUP_FLAG" 2>/dev/null)
if [ "$STORED_PID" != "$$" ]; then
# Different session (different parent PID) — clear stale flag
rm -f "$DEDUP_FLAG" 2>/dev/null
elif find "$DEDUP_FLAG" -mmin -10 2>/dev/null | grep -q .; then
exit 0
else
rm -f "$DEDUP_FLAG" 2>/dev/null
fi
fi
# Lowercase prompt for matching
PROMPT_LOWER=$(echo "$PROMPT" | tr '[:upper:]' '[:lower:]')
# Check for high-stakes keywords
TRIGGERED=0
# Destructive/scoping verbs
if echo "$PROMPT_LOWER" | grep -qE '\b(remove|delete|refactor|rewrite|replace|migrate|restructure|eliminate|strip|extract|consolidate|overhaul|rip out|tear down|gut)\b'; then
TRIGGERED=1
fi
# Scope-limiting words that signal ambiguous intent ("just rename", "only update")
if [ "$TRIGGERED" = "0" ]; then
if echo "$PROMPT_LOWER" | grep -qE '\b(just|only)\b'; then
TRIGGERED=1
fi
fi
# Scope-ambiguous phrases in long prompts (>150 chars)
if [ "$TRIGGERED" = "0" ] && [ "${#PROMPT}" -gt 150 ]; then
if echo "$PROMPT_LOWER" | grep -qE '\b(all|everything|entire|whole|every)\b'; then
TRIGGERED=1
fi
fi
# Not triggered → exit silently
[ "$TRIGGERED" = "0" ] && exit 0
# Write dedup flag with session PID for cross-session detection
echo "$$" > "$DEDUP_FLAG" 2>/dev/null
# Inject echo protocol
ECHO_MSG="HIGH-STAKES OPERATION DETECTED. Before proceeding:
1. Restate the user's intent in ONE sentence
2. List what WILL change (specific files/functions)
3. List what will NOT change
4. State your success criteria
Proceed ONLY after this confirmation step."
if command -v jq >/dev/null 2>&1; then
jq -n --arg ctx "$ECHO_MSG" '{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","additionalContext":$ctx}}'
else
safe_msg=${ECHO_MSG//\\/\\\\}
safe_msg=${safe_msg//\"/\\\"}
safe_msg=$(echo "$safe_msg" | tr '\n' ' ')
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"UserPromptSubmit\",\"additionalContext\":\"$safe_msg\"}}"
fi
exit 0