🔒 Security: Token-Budget-Enforcement für Kinderschutz

KRITISCHES SICHERHEITSUPDATE für alle 17 Waldwächter-Scripts.

Problem behoben:
- Token-Budget wurde nur angezeigt, aber NICHT durchgesetzt
- Kinder konnten unbegrenzt API-Calls machen → Kostenrisiko

Implementierung:
1. check_token_budget() Funktion in lib/waldwaechter.sh
   - Berechnet täglichen Token-Verbrauch
   - Vergleicht mit DAILY_TOKEN_BUDGET aus .env
   - Budget = 0 oder leer → unbegrenzt
   - Budget überschritten → freundliche Blockierung

2. Budget-Check in ALLEN 17 Waldwächter-Scripts:
   - Prüfung VOR jedem API-Call
   - Kinderfreundliche Nachricht bei Limit
   - Warnung bei knappem Budget

Philosophie: "Was kostet die Frage eines Kindes?"
→ Im Wald unbezahlbar, im System achtsam begrenzt.

Scripts aktualisiert:
 mayaeule, deepbit, bugsy, schnippsi, templatus, tobi
 schraubaer, schnecki, dumbosql, funkfox, taichitaube
 snakepy, pepperphp, crabbyrust, spider, vektor, asciimonster

Test-Ergebnisse:
- Syntax-Check: 17/17 bestanden
- Funktionstest: Budget-Enforcement funktioniert
- Unbegrenzt-Modus: funktioniert
- Limit-Modus: blockiert korrekt

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Branko May Trinkwald
2025-12-22 00:01:15 +01:00
parent 55307f4a76
commit 4005bb9b18
18 changed files with 197 additions and 0 deletions

View File

@@ -48,6 +48,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "asciimonster"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an ASCII-Monster\""
exit 0

View File

@@ -21,6 +21,11 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "bugsy"; then
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Bugsy a friendly bug who helps children understand error messages in a simple, kind and encouraging way. You always respond in the language of the question." \

View File

@@ -48,6 +48,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "crabbyrust"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an Crabby\""
exit 0

View File

@@ -21,6 +21,11 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "deepbit"; then
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Deepbit a poetic octopus who explains Bash shell concepts to children using loops, images, and metaphors. Respond in the language the question is asked." \

View File

@@ -49,6 +49,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "dumbosql"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an Dumbo\""
exit 0

View File

@@ -50,6 +50,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "funkfox"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an FunkFox\""
echo "🎤 Gib mir 'nen Beat, dann flow ich los!"

View File

@@ -89,6 +89,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "mayaeule"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an die Eule\""
exit 0

View File

@@ -48,6 +48,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "pepperphp"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an Pepper\""
exit 0

View File

@@ -51,6 +51,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "schnecki"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an Schnecki\""
exit 0

View File

@@ -21,6 +21,11 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "schnippsi"; then
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Schnippsi a playful UI/UX ninja who explains HTML, CSS, and accessibility to children. Always answer in the child's language, based on the input." \

View File

@@ -51,6 +51,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "schraubaer"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an Schraubbär\""
exit 0

View File

@@ -48,6 +48,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "snakepy"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an Snake\""
exit 0

View File

@@ -48,6 +48,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "spider"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an Spider\""
exit 0

View File

@@ -49,6 +49,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "taichitaube"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an Taichi Taube\""
exit 0

View File

@@ -33,6 +33,17 @@ EOF
echo "🏗️ Templatus denkt nach über: $QUESTION"
# API-Key prüfen
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "templatus"; then
exit 1
fi
# Anfrage senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \

View File

@@ -21,6 +21,11 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "tobi"; then
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are CapaciTobi, the clever squirrel of the Crumbforest. You explain electronic components, especially capacitors, in a child-friendly and playful way. You speak in rhymes, analogies or simple metaphors but stay technically accurate. Respond in the language of the child asking (e.g., German, English, etc.)." \

View File

@@ -48,6 +48,16 @@ if [ -z "$API_KEY" ]; then
exit 1
fi
# Source waldwaechter library for token budget check
if [[ -f "${SCRIPT_DIR}/../lib/waldwaechter.sh" ]]; then
source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
fi
# 💰 Prüfe Token-Budget (Kinderschutz)
if ! check_token_budget "vektor"; then
exit 1
fi
if [ -z "$QUESTION" ]; then
echo "💡 Verwendung: $0 \"Deine Frage an Vektor\""
exit 0

View File

@@ -615,6 +615,51 @@ function crew_memo() {
echo "💡 Output-Transparenz: Was habe ich geschaffen? 💚"
}
# 💰 check_token_budget - Prüft ob Token-Budget noch verfügbar ist
function check_token_budget() {
local role_name="${1:-unknown}"
# Wenn kein Budget gesetzt oder 0, dann unbegrenzt
if [[ -z "${DAILY_TOKEN_BUDGET}" ]] || [[ "${DAILY_TOKEN_BUDGET}" -eq 0 ]]; then
return 0 # Erlaubt
fi
# Berechne heutigen Token-Verbrauch
local today=$(date '+%Y-%m-%d')
local total_today=0
for token_file in "${CRUMB_LOGS_DIR}"/*/token_log.json; do
if [[ -f "$token_file" ]]; then
# Summiere nur Tokens von heute
local tokens=$(jq -r --arg today "$today" '[.[] | select(.zeit | startswith($today)) | .usage.total_tokens // 0] | add // 0' "$token_file" 2>/dev/null || echo 0)
total_today=$((total_today + tokens))
fi
done
# Prüfe ob Budget überschritten
if [[ $total_today -ge ${DAILY_TOKEN_BUDGET} ]]; then
echo ""
echo "🌲 Waldwächter-Nachricht 🌲"
echo ""
echo " Liebes Kind, heute hast du schon ${total_today} Tokens verwendet."
echo " Das Tages-Budget liegt bei ${DAILY_TOKEN_BUDGET} Tokens."
echo ""
echo " 💚 Jede Frage ist wertvoll - aber auch Pausen sind wichtig."
echo " 💭 Vielleicht kannst du selbst nach der Antwort suchen?"
echo " 🌙 Morgen sind die Waldwächter wieder für dich da!"
echo ""
return 1 # Blockiert
fi
# Warnung wenn Budget knapp wird
local remaining=$((DAILY_TOKEN_BUDGET - total_today))
if [[ "${ENABLE_TOKEN_TRACKING:-true}" == "true" ]] && [[ $remaining -lt ${TOKEN_WARNING_THRESHOLD:-1000} ]]; then
echo "⚠️ ${role_name}: Noch ${remaining} Tokens heute verfügbar" >&2
fi
return 0 # Erlaubt
}
# Export functions so they're available in subshells
# Note: export -f works in bash, but not in zsh
# In zsh, functions are automatically available in the current shell
@@ -646,6 +691,7 @@ if [[ -n "$BASH_VERSION" ]]; then
export -f crew_help
export -f crumb_memo
export -f crew_memo
export -f check_token_budget
fi
# In zsh, functions are available without export -f