1200+ distilled gold examples, journal system, redstone mastery, safety awareness
Distilled Training Data (1,203 examples): - 341 initial gold (plugins, enchantments, builds, effects, god, errors) - 165 buildings + pipeline (100 structures built on dev, 65 request→query→act) - 24 safety-aware (worldborder, safe tp, intentional harm, gamemode checks) - 17 advanced logic (decanonized items, redstone gates, iterative builds) - 12 redstone mastery (NOT/OR/AND/XOR/RS-latch/T-flip-flop/comparator/clock) - 7 circuit verification and diagnosis - 1 compact comparator gates - 10 redstone methodology (build→test→save→recall→learn from mistakes) - 8 player journal usage - 29 creative+uncommon+pipeline+god with full tool chains Player Journal System: - agent/tools/player_journal.py — per-player text files (1-10 lines) - journal.read + journal.write tool schemas added - Cross-contaminated: God and Sudo share same journal per player - Includes sentiment, relationship, builds, preferences, skill level Redstone Engineering: - agent/prompts/redstone_rules.md — baked-in wall torch, dedicated lead, repeater rules - Learned from 4 iterations of 8-switch circuit: wall_torch on back face, not top - T-junction bypass prevention: dedicated lead wire between merge and NOT block - RCON limitation: can build circuits but cannot test them (lever toggle doesn't propagate) Training Data Cleaning: - 466 @s→@p fixes, 10 template commands removed - 12 outdated refusals replaced with correct plugin commands - Data de-duped across all sources Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,12 +17,64 @@ from typing import Dict, Any, List, Tuple
|
||||
# Commands allowed for execution via the assistant.
|
||||
# Anything not on this list is blocked.
|
||||
ALLOWED_PREFIXES = [
|
||||
# Vanilla commands
|
||||
'give ', 'effect ', 'xp ', 'tp ', 'teleport ',
|
||||
'time ', 'weather ', 'execute ',
|
||||
'kill ', 'summon ', 'tellraw ',
|
||||
'worldborder ', 'fill ', 'setblock ',
|
||||
'clone ', 'gamemode ', 'data ',
|
||||
'scoreboard ', 'clear ',
|
||||
'scoreboard ', 'clear ', 'say ',
|
||||
'playsound ', 'particle ', 'title ',
|
||||
'enchant ', 'replaceitem ', 'loot ',
|
||||
'tag ', 'team ', 'trigger ',
|
||||
'spawnpoint ', 'setworldspawn ',
|
||||
'difficulty ', 'gamerule ',
|
||||
'advancement ', 'recipe ', 'bossbar ',
|
||||
'spreadplayers ', 'stopsound ',
|
||||
'attribute ', 'item ', 'place ',
|
||||
'ride ', 'damage ', 'return ',
|
||||
'schedule ', 'forceload ',
|
||||
# WorldGuard
|
||||
'rg ', 'region ', 'worldguard ',
|
||||
# CoreProtect
|
||||
'co ', 'coreprotect ',
|
||||
# LuckPerms
|
||||
'lp ', 'luckperms ',
|
||||
# EssentialsX
|
||||
'heal ', 'feed ', 'eco ', 'bal ', 'balance ',
|
||||
'warp ', 'setwarp ', 'delwarp ',
|
||||
'home ', 'sethome ', 'delhome ',
|
||||
'nick ', 'nickname ',
|
||||
'broadcast ', 'msg ', 'r ',
|
||||
'repair ', 'god ', 'fly ',
|
||||
'speed ', 'tpa ', 'tpaccept ', 'tpdeny ',
|
||||
'back ', 'spawn ', 'setspawn ',
|
||||
'essentials ', 'seen ', 'whois ',
|
||||
'mute ', 'jail ', 'kick ',
|
||||
'hat ', 'workbench ', 'enderchest ',
|
||||
'ext ', 'top ', 'near ',
|
||||
'tempban ', 'unban ', 'ban ',
|
||||
# FastAsyncWorldEdit / WorldEdit
|
||||
'worldedit ', '//set', '//replace', '//walls',
|
||||
'//sphere', '//hsphere', '//cyl', '//hcyl',
|
||||
'//pyramid', '//hpyramid',
|
||||
'//copy', '//paste', '//cut', '//rotate',
|
||||
'//flip', '//stack', '//move',
|
||||
'//undo', '//redo',
|
||||
'//pos1', '//pos2', '//wand',
|
||||
'//expand', '//contract', '//shift',
|
||||
'//sel', '//size', '//count',
|
||||
'//drain', '//fixwater', '//fixlava',
|
||||
'//snow', '//thaw', '//green',
|
||||
'//smooth', '//overlay', '//naturalize',
|
||||
'//hollow', '//fill', '//fillr',
|
||||
'//line', '//curve', '//forest',
|
||||
'//flora', '//deform',
|
||||
'//generate', '//gen',
|
||||
'//brush', '//mask', '//tool',
|
||||
'//schematic', '//schem',
|
||||
# Vault (usually called through other plugins)
|
||||
'vault ',
|
||||
]
|
||||
|
||||
# Commands that require explicit confirmation before execution.
|
||||
@@ -47,6 +99,28 @@ SYNTAX_WARNINGS = [
|
||||
(re.compile(r'fire\s+0\s+replace'), 'Legacy fire metadata "0". Use minecraft:fire without metadata in 1.21+.'),
|
||||
]
|
||||
|
||||
# Server-breaking commands — blocked unconditionally, even if on allowlist.
|
||||
# These can crash, stop, or compromise the server.
|
||||
HARD_BLOCKED = [
|
||||
re.compile(r'^stop$', re.I), # shuts down the server
|
||||
re.compile(r'^restart$', re.I), # restarts the server
|
||||
re.compile(r'^op\b', re.I), # grants operator (full admin)
|
||||
re.compile(r'^deop\b', re.I), # revokes operator
|
||||
re.compile(r'^whitelist\b', re.I), # whitelist manipulation
|
||||
re.compile(r'^save-off\b', re.I), # disables world saving
|
||||
re.compile(r'^save-all\b', re.I), # forces save (can cause lag spike)
|
||||
re.compile(r'^reload\b', re.I), # reloads server (unstable)
|
||||
re.compile(r'^ban-ip\b', re.I), # IP ban
|
||||
re.compile(r'^pardon-ip\b', re.I), # IP unban
|
||||
re.compile(r'^debug\b', re.I), # debug profiler
|
||||
re.compile(r'^perf\b', re.I), # performance profiler
|
||||
re.compile(r'^jfr\b', re.I), # Java Flight Recorder
|
||||
re.compile(r'^publish\b', re.I), # opens to LAN
|
||||
re.compile(r'[;&|`$]'), # shell injection characters
|
||||
re.compile(r'^lp\s+.*\bop\b', re.I), # LuckPerms granting op
|
||||
re.compile(r'^lp\s+.*\s\*'), # LuckPerms wildcard permissions
|
||||
]
|
||||
|
||||
AUDIT_LOG_PATH = Path(__file__).resolve().parent.parent.parent / 'data' / 'raw' / 'audit_log.jsonl'
|
||||
|
||||
|
||||
@@ -64,7 +138,8 @@ def validate_command(command: str) -> Dict[str, Any]:
|
||||
}
|
||||
"""
|
||||
cmd = command.strip()
|
||||
if cmd.startswith('/'):
|
||||
# Strip single leading slash (vanilla), but preserve // (WorldEdit)
|
||||
if cmd.startswith('/') and not cmd.startswith('//'):
|
||||
cmd = cmd[1:]
|
||||
|
||||
result = {
|
||||
@@ -75,6 +150,12 @@ def validate_command(command: str) -> Dict[str, Any]:
|
||||
'blocked_reason': None,
|
||||
}
|
||||
|
||||
# Hard-block commands that can break/crash the server regardless of allowlist
|
||||
for pattern in HARD_BLOCKED:
|
||||
if pattern.match(cmd):
|
||||
result['blocked_reason'] = f'Hard-blocked: server-breaking command'
|
||||
return result
|
||||
|
||||
# Check allowlist
|
||||
if not any(cmd.startswith(p) for p in ALLOWED_PREFIXES):
|
||||
result['blocked_reason'] = f'Command prefix not in allowlist. Allowed: {", ".join(p.strip() for p in ALLOWED_PREFIXES[:10])}...'
|
||||
|
||||
Reference in New Issue
Block a user