Skill: jayrizz/openclaw-sacred-rules (version 1.0.0)

--- name: openclaw-sacred-rules description: OpenClaw configuration safety rules to prevent system disasters. Use when: (1) Making OpenClaw config changes, (2) Troubleshooting auth failures, (3) Taking system backups, (4) Recovering from config disasters, (5) User asks about config best practices, or (6) Before enabling/disabling system features like sandbox mode. --- # OpenClaw Sacred Rules The 8 Sacred Rules learned from production disasters. **Never violate these rules.** ## The 8 Sacred Rules ### 1. Verify Backups Before Confirming ```bash # Always verify files exist and are valid ls -la backup-file.json python3 -m json.tool backup-file.json > /dev/null ``` ### 2. Never Edit openclaw.json Manually **Wrong:** `nano ~/.openclaw/openclaw.json` **Right:** Use Python/CLI tools that handle JSON safely ### 3. Never Add Unverified Config Keys Check official docs or ask before adding ANY new configuration keys. ### 4. Never Enable Sandbox Without Backup Sandbox mode can cascade auth failures. Always backup first and test in isolation. ### 5. All Providers Failing = Config Issue If multiple model providers fail simultaneously, suspect recent config changes, not provider outages. ### 6. Prefix Auth Commands with Environment ```bash source ~/.openclaw/.env && openclaw auth <command> ``` ### 7. Anthropic 401 = Check auth-profiles.json Don't read the file directly - use `openclaw status` or CLI tools. ### 8. tool_use without tool_result = Reset Session Corrupted sessions need `/reset` to recover. ## Safe Backup Script Use the provided backup script instead of manual file copying: ```bash scripts/safe_backup.sh ``` ## Cooldown Reset Script When experiencing "all providers unavailable" errors despite valid credentials, the in-memory cooldown state may be stale. Use: ```bash scripts/reset_cooldowns.sh ``` This clears expired cooldowns from auth-profiles.json. **Note:** This is a workaround for a bug where in-memory cooldown state doesn't refresh when file timestamps expire. ## Config Validation Before applying config changes: ```bash scripts/config_validator.py ~/.openclaw/openclaw.json ``` ## Recovery Procedures When you break a rule, see `references/recovery.md` for step-by-step recovery procedures. ## Auth Troubleshooting For auth issues, use the safe checker: ```bash scripts/auth_checker.sh ``` **Never directly read auth-profiles.json** - use the checker script instead.

path: references/recovery.md
content: # Recovery Procedures for Sacred Rule Violations

Each rule violation has specific recovery steps. Follow these procedures when you've broken a rule.

## Table of Contents
- Rule 1: Unverified Backup
- Rule 2: Manual JSON Edit  
- Rule 3: Unverified Config Keys
- Rule 4: Sandbox Without Backup
- Rule 5: Ignored Multi-Provider Failure
- Rule 6: Auth Command Without Environment
- Rule 7: Read auth-profiles.json Directly
- Rule 8: Ignored Session Corruption
- Rule 9: Stale In-Memory Cooldown (NEW!)

---

## Rule 1 Violation: Unverified Backup

**Symptom**: You assumed backup worked but files are missing/corrupted

**Recovery**:
1. Stop all OpenClaw processes immediately
2. Check if ANY valid config files exist:
   ```bash
   python3 -m json.tool ~/.openclaw/openclaw.json
   python3 -m json.tool ~/.openclaw/agents/main/agent/auth-profiles.json
   ```
3. If files are corrupted, restore from oldest known-good backup
4. If no backups exist, start fresh installation

## Rule 2 Violation: Manual JSON Edit

**Symptom**: Gateway won't start, JSON parse errors

**Recovery**:
1. Restore from backup immediately:
   ```bash
   cp backup/openclaw.json ~/.openclaw/
   ```
2. If no backup, validate syntax:
   ```bash
   python3 -m json.tool ~/.openclaw/openclaw.json
   ```
3. Fix JSON errors using proper JSON editor
4. Restart gateway: `openclaw gateway restart`

## Rule 3 Violation: Unverified Config Keys

**Symptom**: Gateway crashes, unknown configuration warnings

**Recovery**:
1. Restore from pre-change backup
2. Remove the unverified keys:
   ```python
   import json
   with open('~/.openclaw/openclaw.json') as f:
       config = json.load(f)
   # Remove the problematic keys
   del config['problematic_key']
   with open('~/.openclaw/openclaw.json', 'w') as f:
       json.dump(config, f, indent=2)
   ```
3. Restart gateway

## Rule 4 Violation: Sandbox Without Backup

**Symptom**: Auth cascade failures, all providers down

**Recovery**:
1. **IMMEDIATE**: Disable sandbox mode
2. If you have pre-sandbox backup, restore it
3. If no backup, manually disable in config:
   ```python
   import json
   with open('~/.openclaw/openclaw.json') as f:
       config = json.load(f)
   if 'agents' in config and 'defaults' in config['agents']:
       if 'sandbox' in config['agents']['defaults']:
           config['agents']['defaults']['sandbox']['mode'] = 'off'
   with open('~/.openclaw/openclaw.json', 'w') as f:
       json.dump(config, f, indent=2)
   ```
4. Restart gateway
5. Check auth status

## Rule 5 Violation: Ignored Multi-Provider Failure

**Symptom**: Assumed provider outage, didn't check recent config changes

**Recovery**:
1. List recent config changes:
   ```bash
   ls -la ~/.openclaw/openclaw.json
   ls -la ~/.openclaw/.env
   ls -la ~/.openclaw/agents/main/agent/auth-profiles.json
   ```
2. Identify what changed recently (check timestamps)
3. Restore from backup before the change
4. Re-apply changes one at a time with testing

## Rule 6 Violation: Auth Command Without Environment

**Symptom**: Auth commands fail, environment variables not found

**Recovery**:
1. Always prefix with environment:
   ```bash
   source ~/.openclaw/.env && openclaw auth <command>
   ```
2. Verify .env file exists and has correct permissions:
   ```bash
   ls -la ~/.openclaw/.env
   ```
3. If .env is missing, recreate with gateway password

## Rule 7 Violation: Read auth-profiles.json Directly

**Symptom**: Auth system corrupted, files modified unexpectedly

**Recovery**:
1. **NEVER READ THIS FILE AGAIN**
2. Restore from backup immediately:
   ```bash
   cp backup/auth-profiles.json ~/.openclaw/agents/main/agent/
   ```
3. Restart gateway
4. If no backup, regenerate auth profiles:
   ```bash
   source ~/.openclaw/.env && openclaw auth regenerate
   ```

## Rule 9 Violation: Stale In-Memory Cooldown (NEW!)

**Symptom**: All providers show "rate limited" or "unavailable" even though:
- Credentials are valid
- Cooldowns have expired in the file
- You just restarted the gateway

**Root Cause**: OpenClaw bug where in-memory cooldown tracking doesn't refresh when `cooldownUntil` timestamps expire in auth-profiles.json.

**Recovery**:
1. Run the cooldown reset script:
   ```bash
   ./scripts/reset_cooldowns.sh
   ```
2. Or manually edit auth-profiles.json:
   ```bash
   # Remove cooldownUntil, errorCount, lastFailureAt, failureCounts
   python3 -c "
   import json
   with open('$HOME/.openclaw/agents/main/agent/auth-profiles.json') as f:
       data = json.load(f)
   for k in data.get('usageStats', {}):
       data['usageStats'][k].pop('cooldownUntil', None)
       data['usageStats'][k]['errorCount'] = 0
       data['usageStats'][k].pop('lastFailureAt', None)
       data['usageStats'][k]['failureCounts'] = {}
   with open('$HOME/.openclaw/agents/main/agent/auth-profiles.json', 'w') as f:
       json.dump(data, f, indent=2)
   "
   ```
3. Restart gateway if issues persist:
   ```bash
   openclaw gateway restart
   ```

**Prevention**: This is a bug in OpenClaw - submit bug report!

**Symptom**: Orphaned tool_use blocks, incomplete responses

**Recovery**:
1. Tell user to `/reset` their session immediately
2. Check for other corrupted sessions:
   ```bash
   ls -la ~/.openclaw/agents/main/sessions/*.jsonl
   ```
3. Look for sessions with recent tool_use without tool_result
4. Archive corrupted sessions:
   ```bash
   mv corrupted-session.jsonl corrupted-session.jsonl.backup
   ```

## Emergency Recovery

If multiple rules are violated and system is unstable:

1. **Stop everything**: Kill all OpenClaw processes
2. **Restore from backup**: Use most recent known-good backup
3. **Fresh start**: If no backup, consider fresh installation
4. **Document**: Record what happened to prevent recurrence

## Prevention Checklist

Before making ANY config changes:

- [ ] Take verified backup using `scripts/safe_backup.sh`
- [ ] Validate current config with `scripts/config_validator.py`
- [ ] Document what you're about to change
- [ ] Have rollback plan ready
- [ ] Test in isolation if possible

path: scripts/auth_checker.sh
content: #!/bin/bash
# Safe Auth Profile Checker
# Checks auth status without directly reading auth-profiles.json

set -e

echo "🔐 OpenClaw Auth Status Check"
echo "==============================="

# Check if .env file exists (required for auth commands)
if [[ ! -f "$HOME/.openclaw/.env" ]]; then
    echo "❌ Missing .env file at ~/.openclaw/.env"
    echo "   This file should contain gateway passwords and API keys"
    exit 1
fi

echo "✅ Environment file exists"

# Check if auth-profiles.json exists (don't read it)
AUTH_FILE="$HOME/.openclaw/agents/main/agent/auth-profiles.json"
if [[ ! -f "$AUTH_FILE" ]]; then
    echo "❌ Missing auth-profiles.json"
    echo "   Expected location: $AUTH_FILE"
    exit 1
fi

echo "✅ Auth profiles file exists"

# Check file permissions
AUTH_PERMS=$(stat -f "%A" "$AUTH_FILE" 2>/dev/null || stat -c "%a" "$AUTH_FILE" 2>/dev/null)
if [[ "$AUTH_PERMS" != "600" ]]; then
    echo "⚠️  Auth file permissions: $AUTH_PERMS (should be 600)"
else
    echo "✅ Auth file permissions correct (600)"
fi

# Check file modification time (recent changes might indicate issues)
if command -v stat > /dev/null; then
    # macOS stat
    LAST_MODIFIED=$(stat -f "%Sm" -t "%Y-%m-%d %H:%M:%S" "$AUTH_FILE" 2>/dev/null || \
                   stat -c "%y" "$AUTH_FILE" 2>/dev/null | cut -d'.' -f1)
    echo "📅 Last modified: $LAST_MODIFIED"
fi

# Use OpenClaw CLI to check auth status (safe method)
echo ""
echo "🔍 Running OpenClaw status check..."

# Source environment and run status
if source "$HOME/.openclaw/.env" && openclaw status > /tmp/openclaw_status.txt 2>&1; then
    echo "✅ OpenClaw status command succeeded"
    
    # Check for auth-related errors in output (without showing sensitive info)
    if grep -iq "auth" /tmp/openclaw_status.txt; then
        echo "ℹ️  Auth information found in status"
    fi
    
    if grep -iq "error\|fail\|unavailable" /tmp/openclaw_status.txt; then
        echo "⚠️  Potential issues detected in status"
        echo "   Run 'openclaw status' manually to see details"
    fi
    
else
    echo "❌ OpenClaw status command failed"
    echo "   This suggests auth or gateway issues"
    echo "   Check gateway is running: openclaw gateway status"
fi

# Clean up temp file
rm -f /tmp/openclaw_status.txt

echo ""
echo "💡 If experiencing auth issues:"
echo "   1. Check gateway is running: openclaw gateway status"
echo "   2. Verify .env file has correct keys"
echo "   3. Try: source ~/.openclaw/.env && openclaw auth <provider>"
echo "   4. If all else fails: check MEMORY.md for Rule #7"

echo ""
echo "🚫 NEVER directly read auth-profiles.json"
echo "   Use CLI tools only!"

path: scripts/config_validator.py
content: #!/usr/bin/env python3
"""
OpenClaw Config Validator
Safely validates configuration files without modifying them.
"""

import json
import sys
import os
from pathlib import Path

def validate_json_structure(file_path):
    """Validate JSON syntax and structure"""
    try:
        with open(file_path, 'r') as f:
            data = json.load(f)
        return True, data, None
    except json.JSONDecodeError as e:
        return False, None, f"Invalid JSON: {e}"
    except Exception as e:
        return False, None, f"Error reading file: {e}"

def check_openclaw_config(config_data):
    """Check OpenClaw-specific configuration requirements"""
    warnings = []
    errors = []
    
    # Required top-level keys
    required_keys = ['agents', 'gateway']
    for key in required_keys:
        if key not in config_data:
            errors.append(f"Missing required key: {key}")
    
    # Check for sandbox configuration
    if 'agents' in config_data and 'defaults' in config_data['agents']:
        defaults = config_data['agents']['defaults']
        if 'sandbox' in defaults:
            warnings.append("Sandbox configuration detected - ensure you have a backup!")
    
    # Check for memory management keys
    memory_keys = ['compaction', 'contextPruning', 'memorySearch', 'experimental']
    found_memory_keys = []
    
    if 'agents' in config_data and 'defaults' in config_data['agents']:
        for key in memory_keys:
            if key in config_data['agents']['defaults']:
                found_memory_keys.append(key)
    
    if found_memory_keys:
        warnings.append(f"Memory management keys found: {found_memory_keys}")
    
    return warnings, errors

def main():
    if len(sys.argv) != 2:
        print("Usage: python3 config_validator.py <path-to-openclaw.json>")
        sys.exit(1)
    
    config_path = sys.argv[1]
    
    if not os.path.exists(config_path):
        print(f"❌ Error: File not found: {config_path}")
        sys.exit(1)
    
    print(f"🔍 Validating: {config_path}")
    print("")
    
    # Validate JSON structure
    is_valid, config_data, error = validate_json_structure(config_path)
    
    if not is_valid:
        print(f"❌ JSON Validation Failed: {error}")
        sys.exit(1)
    
    print("✅ JSON syntax is valid")
    
    # Check OpenClaw-specific requirements
    warnings, errors = check_openclaw_config(config_data)
    
    if errors:
        print("\n❌ Configuration Errors:")
        for error in errors:
            print(f"  • {error}")
        sys.exit(1)
    
    if warnings:
        print("\n⚠️  Configuration Warnings:")
        for warning in warnings:
            print(f"  • {warning}")
    
    print("\n🎉 Configuration validation completed")
    
    # Show file stats
    file_size = os.path.getsize(config_path)
    print(f"📊 File size: {file_size} bytes")
    print(f"📊 Top-level keys: {list(config_data.keys())}")
    
    if not warnings and not errors:
        print("✅ No issues found!")

if __name__ == "__main__":
    main()

path: scripts/reset_cooldowns.sh
content: #!/bin/bash
# OpenClaw Cooldown Reset Script
# Usage: ./reset_cooldowns.sh
# 
# IMPORTANT: This resets ALL auth profile cooldowns and error states
# Use when experiencing "all providers unavailable" despite valid credentials

set -e

AUTH_FILE="$HOME/.openclaw/agents/main/agent/auth-profiles.json"

echo "🔧 OpenClaw Cooldown Reset"
echo "=========================="

# Check if file exists
if [[ ! -f "$AUTH_FILE" ]]; then
    echo "❌ Auth file not found: $AUTH_FILE"
    exit 1
fi

echo "✅ Auth file found: $AUTH_FILE"

# Backup before modifying
BACKUP_DIR="$HOME/openclaw-backups/cooldown-reset-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
cp "$AUTH_FILE" "$BACKUP_DIR/"
echo "📦 Backed up auth file to: $BACKUP_DIR"

# Reset cooldowns using Python
python3 << 'EOF'
import json

auth_file = '/Users/admin/.openclaw/agents/main/agent/auth-profiles.json'

with open(auth_file, 'r') as f:
    data = json.load(f)

reset_count = 0

# Clear all cooldowns and error states
for key in data.get('usageStats', {}):
    profile = data['usageStats'][key]
    
    if 'cooldownUntil' in profile:
        del profile['cooldownUntil']
        reset_count += 1
        print(f"  ✓ Cleared cooldown from {key}")
    
    if 'errorCount' in profile:
        profile['errorCount'] = 0
    
    if 'lastFailureAt' in profile:
        del profile['lastFailureAt']
    
    if 'failureCounts' in profile:
        profile['failureCounts'] = {}

with open(auth_file, 'w') as f:
    json.dump(data, f, indent=2)

print(f"\n✅ Reset {reset_count} cooldowns")
print("💡 Restart gateway if issues persist: openclaw gateway restart")
EOF

echo ""
echo "🎉 Cooldown reset complete!"
echo ""
echo "⚠️  NOTE: This is a workaround for a bug where in-memory"
echo "   cooldown state doesn't refresh when file timestamps expire."
echo "   The root cause needs to be fixed in OpenClaw core."

path: scripts/safe_backup.sh
content: #!/bin/bash
# Safe OpenClaw Backup Script
# Creates verified backups without reading system files directly

set -e

# Generate timestamp-based backup directory
TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
BACKUP_DIR="$HOME/openclaw-backups/backup-$TIMESTAMP"

echo "🔒 OpenClaw Safe Backup - $TIMESTAMP"
echo "Creating backup directory: $BACKUP_DIR"

# Create backup directory
mkdir -p "$BACKUP_DIR"

# Critical files to backup (copy only, never read)
declare -a FILES=(
    "$HOME/.openclaw/openclaw.json"
    "$HOME/.openclaw/.env"
    "$HOME/.openclaw/agents/main/agent/auth-profiles.json"
)

# Optional files (if they exist)
declare -a OPTIONAL_FILES=(
    "$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
)

echo "📁 Backing up critical files..."
for file in "${FILES[@]}"; do
    if [[ -f "$file" ]]; then
        echo "  ✓ $(basename "$file")"
        cp "$file" "$BACKUP_DIR/"
    else
        echo "  ✗ Missing: $file"
        exit 1
    fi
done

echo "📁 Backing up optional files..."
for file in "${OPTIONAL_FILES[@]}"; do
    if [[ -f "$file" ]]; then
        echo "  ✓ $(basename "$file")"
        cp "$file" "$BACKUP_DIR/"
    else
        echo "  - Skipped: $(basename "$file") (not found)"
    fi
done

echo "✅ Verification..."
# Verify JSON files without reading content (just structure)
if python3 -m json.tool "$BACKUP_DIR/openclaw.json" > /dev/null 2>&1; then
    echo "  ✓ openclaw.json is valid JSON"
else
    echo "  ✗ openclaw.json is invalid JSON"
    exit 1
fi

if python3 -m json.tool "$BACKUP_DIR/auth-profiles.json" > /dev/null 2>&1; then
    echo "  ✓ auth-profiles.json is valid JSON"
else
    echo "  ✗ auth-profiles.json is invalid JSON"
    exit 1
fi

# Verify .env file exists and is readable (don't read content)
if [[ -r "$BACKUP_DIR/.env" ]]; then
    echo "  ✓ .env file backed up"
else
    echo "  ✗ .env file backup failed"
    exit 1
fi

echo "🎉 Backup completed successfully!"
echo "📂 Location: $BACKUP_DIR"
echo "📊 Files: $(ls -1 "$BACKUP_DIR" | wc -l | tr -d ' ')"
echo ""
echo "To restore: cp $BACKUP_DIR/* ~/.openclaw/"
echo "Remember: Restart gateway after restore"

Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: suspicious | SkillSpector: suspicious (HIGH)