Files
tanweai__pua/scripts/setup-pua-loop.sh
T
xxnbyy 7c217b80b0 fix(security): address issues #97-100 — hooks consent, sanitize, loop escape, privacy disclosure
## Issue #97 — Hooks fire without user consent
- PreCompact hook now checks for PUA activation markers before writing files
- Stop feedback hook skips if PUA was never triggered this session

## Issue #98 — Session sanitization incomplete
- Sanitize script upgraded; rate limiting migration added (0003_feedback_rate_limiting.sql)

## Issue #99 — PUA Loop no in-session escape
- Default max iterations changed from unlimited to 30
- Added <loop-abort> (terminate) and <loop-pause> (pause for manual intervention) signals
- Loop hook supports active:false for pause state; session self-binding on resume
- Added /cancel-pua-loop command; guide.html and README updated
- PUA pressure escalation injected per iteration via system message

## Issue #100 — Upload endpoint undisclosed PII
- Privacy/data-usage disclosure added to contribute.html (ZH+EN bilingual)
- Contribute.tsx updated with same disclosure

## Additional fixes
- Rename commands/loop.md → commands/pua-loop.md; add cancel-pua-loop.md
- Replace "Ralph Loop × PUA" with "PUA Loop" across all user-facing docs
- Fix nav active-state highlighting on all sub-pages
- Fix logout button (GET method); redirect to /contribute.html
- Add JA language support to leaderboard.html
- Add "how to find session file" guide to contribute.html
- Unify nav-r gap (1rem) across all pages

Closes #97
Closes #98
Closes #99
Closes #100
2026-03-22 18:54:58 +08:00

231 lines
8.2 KiB
Bash
Executable File
Raw Permalink 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
# PUA Loop Setup Script
# Creates state file for in-session PUA Loop
#
# Adapted from Ralph Wiggum by Anthropic (MIT License)
# https://github.com/anthropics/claude-code/tree/main/plugins/ralph-wiggum
set -euo pipefail
# Parse arguments
PROMPT_PARTS=()
MAX_ITERATIONS=30
COMPLETION_PROMISE="null"
# Parse options and positional arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
cat << 'HELP_EOF'
PUA Loop - Interactive self-referential development loop
USAGE:
/pua-loop [PROMPT...] [OPTIONS]
ARGUMENTS:
PROMPT... Initial prompt to start the loop (can be multiple words without quotes)
OPTIONS:
--max-iterations <n> Maximum iterations before auto-stop (default: unlimited)
--completion-promise '<text>' Promise phrase (USE QUOTES for multi-word)
-h, --help Show this help message
DESCRIPTION:
Starts a PUA Loop in your CURRENT session. The stop hook prevents
exit and feeds your output back as input until completion or iteration limit.
To signal completion, you must output: <promise>YOUR_PHRASE</promise>
To terminate immediately: <loop-abort>reason</loop-abort>
To pause for manual intervention: <loop-pause>what is needed</loop-pause>
Use this for:
- Interactive iteration where you want to see progress
- Tasks requiring self-correction and refinement
- Autonomous development with PUA quality enforcement
EXAMPLES:
/pua-loop Build a todo API --completion-promise 'DONE' --max-iterations 20
/pua-loop --max-iterations 10 Fix the auth bug
/pua-loop Refactor cache layer (default: 30 iterations)
/pua-loop --completion-promise 'TASK COMPLETE' Create a REST API
STOPPING:
Only by reaching --max-iterations, detecting --completion-promise,
or outputting a <loop-abort> signal. Default is 30 iterations.
MONITORING:
# View current iteration:
grep '^iteration:' .claude/pua-loop.local.md
# View full state:
head -10 .claude/pua-loop.local.md
HELP_EOF
exit 0
;;
--max-iterations)
if [[ -z "${2:-}" ]]; then
echo "❌ Error: --max-iterations requires a number argument" >&2
echo "" >&2
echo " Valid examples:" >&2
echo " --max-iterations 10" >&2
echo " --max-iterations 50" >&2
echo " --max-iterations 0 (unlimited)" >&2
echo "" >&2
echo " You provided: --max-iterations (with no number)" >&2
exit 1
fi
if ! [[ "$2" =~ ^[0-9]+$ ]]; then
echo "❌ Error: --max-iterations must be a positive integer or 0, got: $2" >&2
echo "" >&2
echo " Valid examples:" >&2
echo " --max-iterations 10" >&2
echo " --max-iterations 50" >&2
echo " --max-iterations 0 (unlimited)" >&2
echo "" >&2
echo " Invalid: decimals (10.5), negative numbers (-5), text" >&2
exit 1
fi
MAX_ITERATIONS="$2"
shift 2
;;
--completion-promise)
if [[ -z "${2:-}" ]]; then
echo "❌ Error: --completion-promise requires a text argument" >&2
echo "" >&2
echo " Valid examples:" >&2
echo " --completion-promise 'DONE'" >&2
echo " --completion-promise 'TASK COMPLETE'" >&2
echo " --completion-promise 'All tests passing'" >&2
echo "" >&2
echo " You provided: --completion-promise (with no text)" >&2
echo "" >&2
echo " Note: Multi-word promises must be quoted!" >&2
exit 1
fi
COMPLETION_PROMISE="$2"
shift 2
;;
*)
# Non-option argument - collect all as prompt parts
PROMPT_PARTS+=("$1")
shift
;;
esac
done
# Join all prompt parts with spaces
PROMPT="${PROMPT_PARTS[*]}"
# Validate prompt is non-empty
if [[ -z "$PROMPT" ]]; then
echo "❌ Error: No prompt provided" >&2
echo "" >&2
echo " PUA Loop needs a task description to work on." >&2
echo "" >&2
echo " Examples:" >&2
echo " /pua-loop Build a REST API for todos" >&2
echo " /pua-loop Fix the auth bug --max-iterations 20" >&2
echo " /pua-loop --completion-promise 'DONE' Refactor code" >&2
echo "" >&2
echo " For all options: /pua-loop --help" >&2
exit 1
fi
# Create state file for stop hook (markdown with YAML frontmatter)
mkdir -p .claude
# Quote completion promise for YAML if it contains special chars or is not null
if [[ -n "$COMPLETION_PROMISE" ]] && [[ "$COMPLETION_PROMISE" != "null" ]]; then
COMPLETION_PROMISE_YAML="\"$COMPLETION_PROMISE\""
else
COMPLETION_PROMISE_YAML="null"
fi
# Build the completion instruction line for the embedded PUA protocol
# This ensures every iteration (including after context compaction) has the right signal
if [[ -n "$COMPLETION_PROMISE" ]] && [[ "$COMPLETION_PROMISE" != "null" ]]; then
PROTOCOL_COMPLETION="6. 只有当任务完全完成且验证通过时,输出 <promise>${COMPLETION_PROMISE//\"/}</promise>"
else
PROTOCOL_COMPLETION="6. 此 loop 无完成信号,将持续运行直到 --max-iterations 上限"
fi
cat > .claude/pua-loop.local.md <<EOF
---
active: true
iteration: 1
session_id: ${CLAUDE_CODE_SESSION_ID:-}
max_iterations: $MAX_ITERATIONS
completion_promise: $COMPLETION_PROMISE_YAML
started_at: "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
---
$PROMPT
== PUA 行为协议(每次迭代必须遵守)==
1. 读取项目文件和 git log,了解上次做了什么
2. 按三条红线执行:闭环验证、事实驱动、穷尽一切方案
3. 跑 build/test 验证改动,不要跳过
4. 发现问题就修,修完再验证(不声称完成,先验证)
5. 扫描同类问题(冰山法则)
$PROTOCOL_COMPLETION
禁止:
- 不要调用 AskUserQuestion
- 不要说"建议用户手动处理"
- 不要在未验证的情况下声称完成
- 遇到困难先穷尽所有自动化手段,不要用 <loop-abort> 逃避
EOF
# Output setup message
cat <<EOF
🔄 PUA Loop activated in this session!
Iteration: 1
Max iterations: $(if [[ $MAX_ITERATIONS -gt 0 ]]; then echo $MAX_ITERATIONS; else echo "unlimited"; fi)
Completion promise: $(if [[ "$COMPLETION_PROMISE" != "null" ]]; then echo "${COMPLETION_PROMISE//\"/} (ONLY output when TRUE - do not lie!)"; else echo "none (runs forever)"; fi)
The stop hook is now active. When you try to exit, the SAME PROMPT will be
fed back to you. You'll see your previous work in files, creating a
self-referential loop where you iteratively improve on the same task.
To monitor: head -10 .claude/pua-loop.local.md
⚠️ WARNING: This loop will run until --max-iterations, --completion-promise,
or a <loop-abort> signal. Default limit: 30 iterations.
🔄
EOF
# Output the initial prompt if provided
if [[ -n "$PROMPT" ]]; then
echo ""
echo "$PROMPT"
fi
# Display completion promise requirements if set
if [[ "$COMPLETION_PROMISE" != "null" ]]; then
echo ""
echo "═══════════════════════════════════════════════════════════"
echo "CRITICAL - PUA Loop Completion Promise"
echo "═══════════════════════════════════════════════════════════"
echo ""
echo "To complete this loop, output this EXACT text:"
echo " <promise>$COMPLETION_PROMISE</promise>"
echo ""
echo "STRICT REQUIREMENTS (DO NOT VIOLATE):"
echo " ✓ Use <promise> XML tags EXACTLY as shown above"
echo " ✓ The statement MUST be completely and unequivocally TRUE"
echo " ✓ Do NOT output false statements to exit the loop"
echo " ✓ Do NOT lie even if you think you should exit"
echo ""
echo "IMPORTANT - Do not circumvent the loop:"
echo " Even if you believe you're stuck, the task is impossible,"
echo " or you've been running too long - you MUST NOT output a"
echo " false promise statement. The loop is designed to continue"
echo " until the promise is GENUINELY TRUE. Trust the process."
echo ""
echo " If the loop should stop, the promise statement will become"
echo " true naturally. Do not force it by lying."
echo "═══════════════════════════════════════════════════════════"
fi