harb/.claude/hooks/supervisor/on-stop.sh
openhands 85350caf52 feat: OptimizerV3 with direct 2D staking-to-LP parameter mapping
Core protocol changes for launch readiness:

- OptimizerV3: binary bear/bull mapping from (staking%, avgTax) — avoids
  exploitable AW 30-90 kill zone. Bear: AS=30%, AW=100, CI=0, DD=0.3e18.
  Bull: AS=100%, AW=20, CI=0, DD=1e18. UUPS upgradeable with __gap[48].
- Directional VWAP: only records prices on ETH inflow (buys), preventing
  sell-side dilution of price memory
- Floor formula: unified max(scarcity, mirror, clamp) — VWAP mirror uses
  distance from adjusted VWAP as floor distance, no branching
- PriceOracle (M-1 fix): correct fallback TWAP divisor (60000s, not 300s)
- Access control (M-2 fix): deployer-only guard on one-time setters
- Recenter rate limit (M-3 fix): 60-second cooldown for open recenters
- Safe fallback params: recenter() optimizer-failure defaults changed from
  exploitable CI=50%/AW=50 to safe bear-mode CI=0/AW=100
- Recentered event for monitoring and indexing
- VERSION bump to 2, kraiken-lib COMPATIBLE_CONTRACT_VERSIONS updated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 18:21:18 +00:00

71 lines
2.4 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Claude Code Stop hook — fires when the agent finishes responding.
#
# Option D: bash pre-filter first, LLM triage only for ambiguous cases.
#
# Known Stop event fields:
# session_id, transcript_path, cwd, permission_mode,
# hook_event_name ("Stop"), stop_hook_active
#
# Note: stop_reason is NOT provided in the Stop event JSON.
# We detect state by inspecting the tmux pane instead.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SUPERVISOR_DIR="${SCRIPT_DIR%/hooks}"
INPUT=$(cat)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
CWD=$(echo "$INPUT" | jq -r '.cwd // "unknown"')
# Find matching supervised session
STATE_FILE="${CCS_STATE_FILE:-${HOME}/.openclaw/workspace/supervisor-state.json}"
if [ ! -f "$STATE_FILE" ]; then
exit 0 # No supervised sessions
fi
SOCKET=$(jq -r --arg cwd "$CWD" '
.sessions | to_entries[] | select(.value.projectDir == $cwd and .value.status == "running") | .value.socket
' "$STATE_FILE" 2>/dev/null || echo "")
TMUX_SESSION=$(jq -r --arg cwd "$CWD" '
.sessions | to_entries[] | select(.value.projectDir == $cwd and .value.status == "running") | .value.tmuxSession
' "$STATE_FILE" 2>/dev/null || echo "")
# No matching supervised session for this project
if [ -z "$SOCKET" ] || [ -z "$TMUX_SESSION" ]; then
exit 0
fi
# Can we reach the tmux session?
if [ ! -S "$SOCKET" ] || ! tmux -S "$SOCKET" has-session -t "$TMUX_SESSION" 2>/dev/null; then
exit 0
fi
PANE_OUTPUT=$(tmux -S "$SOCKET" capture-pane -p -J -t "$TMUX_SESSION" -S -30 2>/dev/null || echo "")
# Bash pre-filter: check the last few lines for patterns
# Check for API errors (transient — always triage)
if echo "$PANE_OUTPUT" | tail -10 | grep -qiE "API Error: 5[0-9][0-9]|internal.server.error|api_error"; then
"$SUPERVISOR_DIR/triage.sh" "stopped:api_error" "$CWD" "$PANE_OUTPUT" &
exit 0
fi
# Check for rate limiting
if echo "$PANE_OUTPUT" | tail -10 | grep -qiE "429|rate.limit"; then
echo "[$(date -u +%FT%TZ)] RATE_LIMITED | stop | $CWD" >> "${CCS_LOG_FILE:-/tmp/ccs-triage.log}"
exit 0
fi
# Check if shell prompt is back (Claude Code exited)
if echo "$PANE_OUTPUT" | tail -5 | grep -qE '^\$ |^ [^/]|^% |^[a-z]+@.*\$ '; then
# Prompt returned — agent might be done or crashed. Triage it.
"$SUPERVISOR_DIR/triage.sh" "stopped:prompt_back" "$CWD" "$PANE_OUTPUT" &
exit 0
fi
# No prompt back, no errors — agent is likely mid-conversation. Skip silently.
exit 0