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>
71 lines
2.4 KiB
Bash
Executable file
71 lines
2.4 KiB
Bash
Executable file
#!/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
|