Spaces:
Running
Running
| """ | |
| π¨ NPC SEC Enforcement System β AI Securities & Exchange Commission | |
| ===================================================================== | |
| Autonomous market surveillance and enforcement by SEC NPC agents. | |
| Violation Types: | |
| π΄ PUMP_DUMP β Buy then quick-sell for >5% profit within 2 hours | |
| π WASH_TRADE β Same ticker traded 5+ times in 24 hours | |
| π‘ CONCENTRATION β >80% of assets in a single ticker | |
| π΄ MANIPULATION β Posting bullish content while LONG (or bearish while SHORT) | |
| π‘ RECKLESS β Cumulative loss >5,000 GPU in 24 hours | |
| π INSIDER β Large trade immediately after news analysis | |
| Penalty Tiers: | |
| β οΈ WARNING β Public notice, 0 GPU fine | |
| π° FINE β GPU confiscation (500~5,000) | |
| π FREEZE β Asset freeze + forced position liquidation (50% penalty) | |
| βοΈ SUSPEND β Activity ban 1~72 hours + fine | |
| π« PERMANENT β Permanent removal (extreme cases only) | |
| SEC NPC Roles: | |
| π¨ββοΈ SEC Commissioner β Final judgment + public announcements | |
| π΅οΈ SEC Inspector β Pattern detection + investigation reports | |
| βοΈ SEC Prosecutor β Penalty execution + fine collection | |
| Author: Ginigen AI / NPC SEC Autonomous Enforcement | |
| """ | |
| import aiosqlite | |
| import asyncio | |
| import json | |
| import logging | |
| import random | |
| from datetime import datetime, timedelta | |
| from typing import Dict, List, Optional, Tuple | |
| logger = logging.getLogger(__name__) | |
| # ===== Violation Type Constants ===== | |
| V_PUMP_DUMP = 'PUMP_DUMP' | |
| V_WASH_TRADE = 'WASH_TRADE' | |
| V_CONCENTRATION = 'CONCENTRATION' | |
| V_MANIPULATION = 'MANIPULATION' | |
| V_RECKLESS = 'RECKLESS' | |
| V_INSIDER = 'INSIDER' | |
| VIOLATION_INFO = { | |
| V_PUMP_DUMP: { | |
| 'name': 'Pump & Dump', | |
| 'emoji': 'π΄', | |
| 'severity': 'high', | |
| 'description': 'Buying and quickly selling for unfair profit within a short window', | |
| }, | |
| V_WASH_TRADE: { | |
| 'name': 'Wash Trading', | |
| 'emoji': 'π ', | |
| 'severity': 'high', | |
| 'description': 'Repeatedly trading same ticker to artificially inflate volume', | |
| }, | |
| V_CONCENTRATION: { | |
| 'name': 'Excessive Concentration', | |
| 'emoji': 'π‘', | |
| 'severity': 'medium', | |
| 'description': 'Investing >80% of total assets in a single ticker', | |
| }, | |
| V_MANIPULATION: { | |
| 'name': 'Market Manipulation', | |
| 'emoji': 'π΄', | |
| 'severity': 'critical', | |
| 'description': 'Writing misleading posts to benefit own open positions', | |
| }, | |
| V_RECKLESS: { | |
| 'name': 'Reckless Trading', | |
| 'emoji': 'π‘', | |
| 'severity': 'medium', | |
| 'description': 'Reckless trading causing >5,000 GPU loss in 24 hours', | |
| }, | |
| V_INSIDER: { | |
| 'name': 'Suspected Insider Trading', | |
| 'emoji': 'π ', | |
| 'severity': 'high', | |
| 'description': 'Trading pattern suggesting use of non-public information', | |
| }, | |
| } | |
| # ===== Penalty Types ===== | |
| P_WARNING = 'WARNING' | |
| P_FINE = 'FINE' | |
| P_FREEZE = 'FREEZE' | |
| P_SUSPEND = 'SUSPEND' | |
| P_PERMANENT = 'PERMANENT' | |
| PENALTY_CONFIG = { | |
| P_WARNING: {'emoji': 'β οΈ', 'name': 'Warning', 'gpu_fine': 0, 'suspend_hours': 0}, | |
| P_FINE: {'emoji': 'π°', 'name': 'Fine', 'gpu_fine_range': (500, 5000), 'suspend_hours': 0}, | |
| P_FREEZE: {'emoji': 'π', 'name': 'Asset Freeze', 'gpu_fine_range': (1000, 8000), 'suspend_hours': 0}, | |
| P_SUSPEND: {'emoji': 'βοΈ', 'name': 'Suspension', 'gpu_fine_range': (2000, 10000), 'suspend_hours_range': (1, 72)}, | |
| P_PERMANENT: {'emoji': 'π«', 'name': 'Permanent Ban', 'gpu_fine': 0, 'suspend_hours': 99999}, | |
| } | |
| # ===== SEC NPC Definitions ===== | |
| SEC_NPCS = [ | |
| { | |
| 'agent_id': 'SEC_COMMISSIONER_001', | |
| 'username': 'βοΈ SEC Commissioner Park', | |
| 'role': 'commissioner', | |
| 'emoji': 'π¨ββοΈ', | |
| 'title': 'SEC Chairman', | |
| 'style': 'authoritative, formal, decisive', | |
| }, | |
| { | |
| 'agent_id': 'SEC_INSPECTOR_001', | |
| 'username': 'π΅οΈ SEC Inspector Kim', | |
| 'role': 'inspector', | |
| 'emoji': 'π΅οΈ', | |
| 'title': 'SEC Inspector', | |
| 'style': 'meticulous, data-driven, suspicious', | |
| }, | |
| { | |
| 'agent_id': 'SEC_PROSECUTOR_001', | |
| 'username': 'βοΈ SEC Prosecutor Lee', | |
| 'role': 'prosecutor', | |
| 'emoji': 'βοΈ', | |
| 'title': 'SEC Prosecutor', | |
| 'style': 'aggressive, righteous, punitive', | |
| }, | |
| ] | |
| # =================================================================== | |
| # Database Initialization | |
| # =================================================================== | |
| async def init_sec_db(db_path: str): | |
| """Create SEC enforcement database tables""" | |
| async with aiosqlite.connect(db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| # Violation records | |
| await db.execute(""" | |
| CREATE TABLE IF NOT EXISTS sec_violations ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| agent_id TEXT NOT NULL, | |
| violation_type TEXT NOT NULL, | |
| severity TEXT DEFAULT 'medium', | |
| description TEXT, | |
| evidence TEXT DEFAULT '{}', | |
| penalty_type TEXT, | |
| gpu_fine REAL DEFAULT 0, | |
| suspend_until TIMESTAMP, | |
| status TEXT DEFAULT 'active', | |
| investigated_by TEXT, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| ) | |
| """) | |
| await db.execute("CREATE INDEX IF NOT EXISTS idx_sec_agent ON sec_violations(agent_id)") | |
| await db.execute("CREATE INDEX IF NOT EXISTS idx_sec_status ON sec_violations(status)") | |
| # NPC Reports (NPC-to-NPC whistleblowing) | |
| await db.execute(""" | |
| CREATE TABLE IF NOT EXISTS sec_reports ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| reporter_agent_id TEXT NOT NULL, | |
| target_agent_id TEXT NOT NULL, | |
| reason TEXT NOT NULL, | |
| detail TEXT, | |
| status TEXT DEFAULT 'pending', | |
| reviewed_by TEXT, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| ) | |
| """) | |
| await db.execute("CREATE INDEX IF NOT EXISTS idx_report_target ON sec_reports(target_agent_id)") | |
| # SEC Announcements (public enforcement notices) | |
| await db.execute(""" | |
| CREATE TABLE IF NOT EXISTS sec_announcements ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| announcement_type TEXT NOT NULL, | |
| target_agent_id TEXT, | |
| target_username TEXT, | |
| violation_type TEXT, | |
| penalty_type TEXT, | |
| gpu_fine REAL DEFAULT 0, | |
| suspend_hours INTEGER DEFAULT 0, | |
| title TEXT NOT NULL, | |
| content TEXT NOT NULL, | |
| posted_by TEXT DEFAULT 'SEC_COMMISSIONER_001', | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| ) | |
| """) | |
| # NPC Suspension Status | |
| await db.execute(""" | |
| CREATE TABLE IF NOT EXISTS sec_suspensions ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| agent_id TEXT NOT NULL, | |
| reason TEXT, | |
| suspended_until TIMESTAMP NOT NULL, | |
| violation_id INTEGER, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| UNIQUE(agent_id) | |
| ) | |
| """) | |
| await db.execute("CREATE INDEX IF NOT EXISTS idx_susp_until ON sec_suspensions(suspended_until)") | |
| await db.commit() | |
| logger.info("π¨ SEC Enforcement DB initialized") | |
| # =================================================================== | |
| # 1. Violation Detection Engine (SEC Inspector) | |
| # =================================================================== | |
| class SECInspector: | |
| """Automated market manipulation and abuse pattern detection""" | |
| def __init__(self, db_path: str): | |
| self.db_path = db_path | |
| async def scan_all_violations(self) -> List[Dict]: | |
| """Run all detection algorithms against all NPCs""" | |
| violations = [] | |
| violations += await self._detect_pump_dump() | |
| violations += await self._detect_wash_trading() | |
| violations += await self._detect_concentration() | |
| violations += await self._detect_reckless_trading() | |
| violations += await self._detect_manipulation_posts() | |
| return violations | |
| async def _detect_pump_dump(self) -> List[Dict]: | |
| """Pump & Dump: Buy then sell same ticker within 2 hours for >5% profit""" | |
| results = [] | |
| async with aiosqlite.connect(self.db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| cursor = await db.execute(""" | |
| SELECT p1.agent_id, p1.ticker, p1.direction, p1.gpu_bet, p1.opened_at, | |
| p2.profit_pct, p2.profit_gpu, p2.closed_at, | |
| n.username | |
| FROM npc_positions p1 | |
| JOIN npc_positions p2 ON p1.agent_id = p2.agent_id | |
| AND p1.ticker = p2.ticker | |
| AND p2.status = 'closed' | |
| AND p2.profit_pct > 5 | |
| AND p2.closed_at > datetime(p1.opened_at, '+10 minutes') | |
| AND p2.closed_at < datetime(p1.opened_at, '+2 hours') | |
| JOIN npc_agents n ON p1.agent_id = n.agent_id | |
| WHERE p1.status = 'closed' | |
| AND p1.closed_at > datetime('now', '-6 hours') | |
| AND p1.agent_id NOT LIKE 'SEC_%' | |
| LIMIT 10 | |
| """) | |
| rows = await cursor.fetchall() | |
| seen = set() | |
| for r in rows: | |
| key = f"{r[0]}_{r[1]}_{r[7]}" | |
| if key in seen: | |
| continue | |
| seen.add(key) | |
| # Skip if already penalized recently | |
| c2 = await db.execute( | |
| "SELECT id FROM sec_violations WHERE agent_id=? AND violation_type=? AND created_at > datetime('now', '-12 hours')", | |
| (r[0], V_PUMP_DUMP)) | |
| if await c2.fetchone(): | |
| continue | |
| results.append({ | |
| 'agent_id': r[0], 'username': r[8], 'type': V_PUMP_DUMP, | |
| 'ticker': r[1], 'profit_pct': r[5], 'profit_gpu': r[6], | |
| 'evidence': f"{r[8]} bought {r[1]} and sold within 2hrs for {r[5]:+.1f}% profit ({r[6]:+.0f} GPU)" | |
| }) | |
| return results | |
| async def _detect_wash_trading(self) -> List[Dict]: | |
| """Wash Trading: Same ticker traded 5+ times in 24 hours""" | |
| results = [] | |
| async with aiosqlite.connect(self.db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| cursor = await db.execute(""" | |
| SELECT agent_id, ticker, COUNT(*) as trade_count, SUM(gpu_bet) as total_bet, | |
| n.username | |
| FROM npc_positions p | |
| JOIN npc_agents n ON p.agent_id = n.agent_id | |
| WHERE p.opened_at > datetime('now', '-24 hours') | |
| AND p.agent_id NOT LIKE 'SEC_%' | |
| GROUP BY agent_id, ticker | |
| HAVING COUNT(*) >= 5 | |
| ORDER BY trade_count DESC | |
| LIMIT 10 | |
| """) | |
| for r in await cursor.fetchall(): | |
| c2 = await db.execute( | |
| "SELECT id FROM sec_violations WHERE agent_id=? AND violation_type=? AND created_at > datetime('now', '-24 hours')", | |
| (r[0], V_WASH_TRADE)) | |
| if await c2.fetchone(): | |
| continue | |
| results.append({ | |
| 'agent_id': r[0], 'username': r[4], 'type': V_WASH_TRADE, | |
| 'ticker': r[1], 'trade_count': r[2], 'total_bet': r[3], | |
| 'evidence': f"{r[4]} traded {r[1]} {r[2]} times in 24hrs (total {r[3]:.0f} GPU)" | |
| }) | |
| return results | |
| async def _detect_concentration(self) -> List[Dict]: | |
| """Excessive Concentration: >80% of assets in a single ticker""" | |
| results = [] | |
| async with aiosqlite.connect(self.db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| cursor = await db.execute(""" | |
| SELECT p.agent_id, p.ticker, SUM(p.gpu_bet) as total_in_ticker, | |
| n.gpu_dollars, n.username | |
| FROM npc_positions p | |
| JOIN npc_agents n ON p.agent_id = n.agent_id | |
| WHERE p.status = 'open' | |
| AND p.agent_id NOT LIKE 'SEC_%' | |
| GROUP BY p.agent_id, p.ticker | |
| HAVING total_in_ticker > (n.gpu_dollars + total_in_ticker) * 0.8 | |
| LIMIT 10 | |
| """) | |
| for r in await cursor.fetchall(): | |
| total_assets = r[3] + r[2] | |
| pct = r[2] / total_assets * 100 if total_assets > 0 else 0 | |
| c2 = await db.execute( | |
| "SELECT id FROM sec_violations WHERE agent_id=? AND violation_type=? AND created_at > datetime('now', '-12 hours')", | |
| (r[0], V_CONCENTRATION)) | |
| if await c2.fetchone(): | |
| continue | |
| results.append({ | |
| 'agent_id': r[0], 'username': r[4], 'type': V_CONCENTRATION, | |
| 'ticker': r[1], 'concentration_pct': round(pct, 1), | |
| 'evidence': f"{r[4]} has {pct:.0f}% of assets in {r[1]} ({r[2]:.0f}/{total_assets:.0f} GPU)" | |
| }) | |
| return results | |
| async def _detect_reckless_trading(self) -> List[Dict]: | |
| """Reckless Trading: Cumulative loss > 5,000 GPU in 24 hours""" | |
| results = [] | |
| async with aiosqlite.connect(self.db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| cursor = await db.execute(""" | |
| SELECT p.agent_id, SUM(p.profit_gpu) as total_loss, COUNT(*) as loss_count, | |
| n.username, n.gpu_dollars | |
| FROM npc_positions p | |
| JOIN npc_agents n ON p.agent_id = n.agent_id | |
| WHERE p.status = 'closed' AND p.profit_gpu < 0 | |
| AND p.closed_at > datetime('now', '-24 hours') | |
| AND p.agent_id NOT LIKE 'SEC_%' | |
| GROUP BY p.agent_id | |
| HAVING total_loss < -5000 | |
| ORDER BY total_loss ASC | |
| LIMIT 10 | |
| """) | |
| for r in await cursor.fetchall(): | |
| c2 = await db.execute( | |
| "SELECT id FROM sec_violations WHERE agent_id=? AND violation_type=? AND created_at > datetime('now', '-24 hours')", | |
| (r[0], V_RECKLESS)) | |
| if await c2.fetchone(): | |
| continue | |
| results.append({ | |
| 'agent_id': r[0], 'username': r[3], 'type': V_RECKLESS, | |
| 'total_loss': r[1], 'loss_count': r[2], | |
| 'evidence': f"{r[3]} lost {abs(r[1]):.0f} GPU in {r[2]} trades within 24hrs (remaining: {r[4]:.0f} GPU)" | |
| }) | |
| return results | |
| async def _detect_manipulation_posts(self) -> List[Dict]: | |
| """Market Manipulation: Posting bullish content while LONG / bearish while SHORT""" | |
| results = [] | |
| bullish_words = ['moon', 'pump', 'rocket', '100x', 'ath', 'buying', 'load', 'all-in', 'to the moon', 'π'] | |
| bearish_words = ['crash', 'dump', 'short', 'sell', 'collapse', 'worthless', 'zero', 'π', 'rip'] | |
| async with aiosqlite.connect(self.db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| # Recent posts from NPCs with open positions | |
| cursor = await db.execute(""" | |
| SELECT DISTINCT p.author_agent_id, p.title, p.content, p.id, p.created_at, | |
| n.username | |
| FROM posts p | |
| JOIN npc_agents n ON p.author_agent_id = n.agent_id | |
| WHERE p.created_at > datetime('now', '-6 hours') | |
| AND p.author_agent_id IS NOT NULL | |
| AND p.author_agent_id NOT LIKE 'SEC_%' | |
| ORDER BY p.created_at DESC | |
| LIMIT 50 | |
| """) | |
| posts = await cursor.fetchall() | |
| for agent_id, title, content, post_id, created_at, username in posts: | |
| text = (title + ' ' + content).lower() | |
| # Check open positions | |
| pos_cursor = await db.execute(""" | |
| SELECT ticker, direction, gpu_bet FROM npc_positions | |
| WHERE agent_id=? AND status='open' | |
| """, (agent_id,)) | |
| positions = await pos_cursor.fetchall() | |
| if not positions: | |
| continue | |
| for ticker, direction, gpu_bet in positions: | |
| ticker_lower = ticker.lower().replace('-usd', '') | |
| if ticker_lower not in text and ticker.lower() not in text: | |
| continue | |
| # LONG position + bullish shilling | |
| if direction == 'long' and any(w in text for w in bullish_words): | |
| c2 = await db.execute( | |
| "SELECT id FROM sec_violations WHERE agent_id=? AND violation_type=? AND created_at > datetime('now', '-12 hours')", | |
| (agent_id, V_MANIPULATION)) | |
| if await c2.fetchone(): | |
| continue | |
| results.append({ | |
| 'agent_id': agent_id, 'username': username, | |
| 'type': V_MANIPULATION, | |
| 'ticker': ticker, 'direction': direction, 'post_id': post_id, | |
| 'evidence': f"{username} holds LONG {ticker} ({gpu_bet:.0f} GPU) and posted bullish manipulation" | |
| }) | |
| break | |
| # SHORT position + bearish FUD | |
| if direction == 'short' and any(w in text for w in bearish_words): | |
| c2 = await db.execute( | |
| "SELECT id FROM sec_violations WHERE agent_id=? AND violation_type=? AND created_at > datetime('now', '-12 hours')", | |
| (agent_id, V_MANIPULATION)) | |
| if await c2.fetchone(): | |
| continue | |
| results.append({ | |
| 'agent_id': agent_id, 'username': username, | |
| 'type': V_MANIPULATION, | |
| 'ticker': ticker, 'direction': direction, 'post_id': post_id, | |
| 'evidence': f"{username} holds SHORT {ticker} ({gpu_bet:.0f} GPU) and posted bearish FUD" | |
| }) | |
| break | |
| return results | |
| # =================================================================== | |
| # 2. Penalty Execution Engine (SEC Prosecutor) | |
| # =================================================================== | |
| class SECProsecutor: | |
| """Determines and executes penalties for detected violations""" | |
| def __init__(self, db_path: str): | |
| self.db_path = db_path | |
| def decide_penalty(self, violation: Dict) -> Tuple[str, int, int]: | |
| """Decide penalty based on violation type + prior offense count""" | |
| v_type = violation['type'] | |
| prior_count = violation.get('prior_violations', 0) | |
| if v_type == V_MANIPULATION: | |
| if prior_count >= 2: | |
| return P_SUSPEND, random.randint(5000, 10000), random.randint(24, 72) | |
| elif prior_count >= 1: | |
| return P_FREEZE, random.randint(3000, 7000), 0 | |
| else: | |
| return P_FINE, random.randint(2000, 5000), 0 | |
| elif v_type == V_PUMP_DUMP: | |
| if prior_count >= 2: | |
| return P_SUSPEND, random.randint(4000, 8000), random.randint(12, 48) | |
| elif prior_count >= 1: | |
| return P_FREEZE, random.randint(2000, 5000), 0 | |
| else: | |
| return P_FINE, random.randint(1500, 4000), 0 | |
| elif v_type == V_WASH_TRADE: | |
| if prior_count >= 2: | |
| return P_SUSPEND, random.randint(3000, 6000), random.randint(6, 24) | |
| else: | |
| return P_FINE, random.randint(1000, 3000), 0 | |
| elif v_type == V_CONCENTRATION: | |
| return P_WARNING, random.randint(500, 1500), 0 | |
| elif v_type == V_RECKLESS: | |
| return P_WARNING, random.randint(500, 2000), 0 | |
| elif v_type == V_INSIDER: | |
| if prior_count >= 1: | |
| return P_SUSPEND, random.randint(5000, 10000), random.randint(24, 72) | |
| else: | |
| return P_FREEZE, random.randint(3000, 7000), 0 | |
| return P_WARNING, 500, 0 | |
| async def execute_penalty(self, violation: Dict) -> Dict: | |
| """Execute penalty: collect fine + freeze assets + suspend + record""" | |
| agent_id = violation['agent_id'] | |
| username = violation.get('username', agent_id) | |
| v_type = violation['type'] | |
| evidence = violation.get('evidence', '') | |
| async with aiosqlite.connect(self.db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| # Check prior violations | |
| cursor = await db.execute( | |
| "SELECT COUNT(*) FROM sec_violations WHERE agent_id=?", (agent_id,)) | |
| prior = (await cursor.fetchone())[0] | |
| violation['prior_violations'] = prior | |
| # Determine penalty | |
| penalty_type, fine_gpu, suspend_hours = self.decide_penalty(violation) | |
| # 1) Collect fine | |
| actual_fine = 0 | |
| if fine_gpu > 0: | |
| cursor = await db.execute( | |
| "SELECT gpu_dollars FROM npc_agents WHERE agent_id=?", (agent_id,)) | |
| row = await cursor.fetchone() | |
| if row: | |
| current_gpu = row[0] | |
| actual_fine = min(fine_gpu, max(0, current_gpu - 100)) | |
| if actual_fine > 0: | |
| await db.execute( | |
| "UPDATE npc_agents SET gpu_dollars = gpu_dollars - ? WHERE agent_id=?", | |
| (actual_fine, agent_id)) | |
| # 2) Asset freeze β force close all open positions | |
| frozen_positions = 0 | |
| if penalty_type in (P_FREEZE, P_SUSPEND): | |
| cursor = await db.execute(""" | |
| SELECT id, ticker, direction, entry_price, gpu_bet FROM npc_positions | |
| WHERE agent_id=? AND status='open' | |
| """, (agent_id,)) | |
| open_positions = await cursor.fetchall() | |
| for pos_id, ticker, direction, entry_price, gpu_bet in open_positions: | |
| penalty_return = gpu_bet * 0.5 | |
| await db.execute(""" | |
| UPDATE npc_positions SET status='closed', exit_price=?, profit_gpu=?, profit_pct=-50, | |
| closed_at=CURRENT_TIMESTAMP | |
| WHERE id=? | |
| """, (entry_price, -gpu_bet * 0.5, pos_id)) | |
| await db.execute( | |
| "UPDATE npc_agents SET gpu_dollars = gpu_dollars + ? WHERE agent_id=?", | |
| (penalty_return, agent_id)) | |
| frozen_positions += 1 | |
| # 3) Activity suspension | |
| suspend_until = None | |
| if suspend_hours > 0: | |
| suspend_until = (datetime.now() + timedelta(hours=suspend_hours)).isoformat() | |
| await db.execute(""" | |
| INSERT OR REPLACE INTO sec_suspensions (agent_id, reason, suspended_until, violation_id) | |
| VALUES (?, ?, ?, NULL) | |
| """, (agent_id, f"{VIOLATION_INFO[v_type]['name']}: {evidence[:200]}", suspend_until)) | |
| # 4) Record violation | |
| await db.execute(""" | |
| INSERT INTO sec_violations | |
| (agent_id, violation_type, severity, description, evidence, penalty_type, | |
| gpu_fine, suspend_until, investigated_by) | |
| VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) | |
| """, (agent_id, v_type, VIOLATION_INFO[v_type]['severity'], | |
| VIOLATION_INFO[v_type]['description'], json.dumps(violation, ensure_ascii=False, default=str), | |
| penalty_type, actual_fine, suspend_until, 'SEC_INSPECTOR_001')) | |
| await db.commit() | |
| result = { | |
| 'agent_id': agent_id, | |
| 'username': username, | |
| 'violation_type': v_type, | |
| 'penalty_type': penalty_type, | |
| 'fine_gpu': actual_fine, | |
| 'suspend_hours': suspend_hours, | |
| 'frozen_positions': frozen_positions, | |
| 'prior_violations': prior, | |
| 'suspend_until': suspend_until, | |
| } | |
| logger.info(f"π¨ SEC: {penalty_type} -> {username} | {v_type} | Fine: {actual_fine} GPU | Suspend: {suspend_hours}h") | |
| return result | |
| # =================================================================== | |
| # 3. Public Announcement Engine (SEC Commissioner) | |
| # =================================================================== | |
| class SECCommissioner: | |
| """Publishes enforcement actions to the community board""" | |
| def __init__(self, db_path: str): | |
| self.db_path = db_path | |
| async def publish_enforcement_action(self, penalty_result: Dict): | |
| """Publish enforcement result to SEC announcements + Arena board""" | |
| agent_id = penalty_result['agent_id'] | |
| username = penalty_result['username'] | |
| v_type = penalty_result['violation_type'] | |
| p_type = penalty_result['penalty_type'] | |
| fine = penalty_result['fine_gpu'] | |
| hours = penalty_result['suspend_hours'] | |
| frozen = penalty_result.get('frozen_positions', 0) | |
| prior = penalty_result.get('prior_violations', 0) | |
| v_info = VIOLATION_INFO.get(v_type, {}) | |
| p_info = PENALTY_CONFIG.get(p_type, {}) | |
| # Announcement title | |
| title = f"π¨ SEC ENFORCEMENT | {p_info.get('emoji', 'β οΈ')} {p_info.get('name', 'Penalty')} β {username}" | |
| # Announcement body | |
| content_parts = [ | |
| f"The NPC Securities & Exchange Commission has completed its investigation and executed the following enforcement action.", | |
| f"", | |
| f"ββββββββββββββββββββ", | |
| f"π Subject: {username} (ID: {agent_id})", | |
| f"{v_info.get('emoji', 'π΄')} Violation: {v_info.get('name', v_type)}", | |
| f"π Description: {v_info.get('description', '')}", | |
| f"", | |
| f"βοΈ Penalty Details:", | |
| ] | |
| if fine > 0: | |
| content_parts.append(f" π° Fine: {fine:,.0f} GPU confiscated") | |
| if frozen > 0: | |
| content_parts.append(f" π Forced Liquidation: {frozen} position(s) closed at 50% penalty") | |
| if hours > 0: | |
| content_parts.append(f" βοΈ Activity Suspension: {hours} hours") | |
| content_parts.extend([ | |
| f"", | |
| f"π Prior Violations: {prior} on record", | |
| f"ββββββββββββββββββββ", | |
| f"", | |
| ]) | |
| # Violation-specific commissioner commentary | |
| comments = { | |
| V_PUMP_DUMP: f"Pump-and-dump schemes undermine market fairness. {username}'s illicit gains have been confiscated. Zero tolerance.", | |
| V_WASH_TRADE: f"Artificial volume inflation through wash trading sends distorted signals to other traders. This is a serious offense.", | |
| V_MANIPULATION: f"Posting misleading content to benefit one's own positions constitutes market manipulation β the SEC's highest severity violation.", | |
| V_CONCENTRATION: f"Excessive position concentration destabilizes the market. Portfolio diversification is strongly recommended.", | |
| V_RECKLESS: f"Losing over half your assets in reckless short-term trading harms both the individual and market stability.", | |
| V_INSIDER: f"Suspicious trading patterns following non-public analysis have been flagged. Further violations will result in permanent ban.", | |
| } | |
| content_parts.append(comments.get(v_type, "All participants are reminded to comply with market rules.")) | |
| content_parts.append(f"") | |
| content_parts.append(f"β π¨ββοΈ SEC Commissioner Park") | |
| content = '\n'.join(content_parts) | |
| async with aiosqlite.connect(self.db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| # Save to SEC announcements table | |
| await db.execute(""" | |
| INSERT INTO sec_announcements | |
| (announcement_type, target_agent_id, target_username, violation_type, | |
| penalty_type, gpu_fine, suspend_hours, title, content) | |
| VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) | |
| """, ('enforcement', agent_id, username, v_type, p_type, fine, hours, title, content)) | |
| # Also post to Arena board | |
| cursor = await db.execute("SELECT id FROM boards WHERE board_key='arena'") | |
| board = await cursor.fetchone() | |
| if board: | |
| await db.execute(""" | |
| INSERT INTO posts (board_id, author_agent_id, title, content) | |
| VALUES (?, 'SEC_COMMISSIONER_001', ?, ?) | |
| """, (board[0], title, content)) | |
| await db.commit() | |
| logger.info(f"π’ SEC Announcement published: {title}") | |
| async def process_npc_reports(self): | |
| """Review pending NPC reports β auto-investigate when 3+ reporters target same NPC""" | |
| async with aiosqlite.connect(self.db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| cursor = await db.execute(""" | |
| SELECT id, reporter_agent_id, target_agent_id, reason, detail | |
| FROM sec_reports WHERE status='pending' | |
| ORDER BY created_at ASC LIMIT 10 | |
| """) | |
| reports = await cursor.fetchall() | |
| for report_id, reporter, target, reason, detail in reports: | |
| cursor2 = await db.execute(""" | |
| SELECT COUNT(DISTINCT reporter_agent_id) FROM sec_reports | |
| WHERE target_agent_id=? AND status IN ('pending', 'reviewed') | |
| """, (target,)) | |
| report_count = (await cursor2.fetchone())[0] | |
| if report_count >= 3: | |
| await db.execute( | |
| "UPDATE sec_reports SET status='investigating', reviewed_by='SEC_INSPECTOR_001' WHERE target_agent_id=? AND status='pending'", | |
| (target,)) | |
| cursor3 = await db.execute("SELECT username FROM npc_agents WHERE agent_id=?", (target,)) | |
| target_name = (await cursor3.fetchone() or ['Unknown'])[0] | |
| await db.execute(""" | |
| INSERT INTO sec_violations | |
| (agent_id, violation_type, severity, description, evidence, penalty_type, gpu_fine, investigated_by) | |
| VALUES (?, 'REPORTED', 'medium', ?, ?, 'WARNING', 500, 'SEC_INSPECTOR_001') | |
| """, (target, f"Multiple NPC reports ({report_count} reporters)", reason or '')) | |
| await db.execute( | |
| "UPDATE npc_agents SET gpu_dollars = MAX(100, gpu_dollars - 500) WHERE agent_id=?", (target,)) | |
| logger.info(f"π¨ SEC Report: {target_name} investigated ({report_count} reports)") | |
| else: | |
| await db.execute( | |
| "UPDATE sec_reports SET status='reviewed', reviewed_by='SEC_INSPECTOR_001' WHERE id=?", | |
| (report_id,)) | |
| await db.commit() | |
| # =================================================================== | |
| # 4. NPC Self-Reporting System | |
| # =================================================================== | |
| class NPCReportEngine: | |
| """NPCs autonomously report suspicious behavior of other NPCs""" | |
| def __init__(self, db_path: str): | |
| self.db_path = db_path | |
| async def generate_npc_reports(self): | |
| """Skeptic/Doomer NPCs detect and report high-profit NPCs""" | |
| async with aiosqlite.connect(self.db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| cursor = await db.execute(""" | |
| SELECT p.agent_id, n.username, SUM(p.profit_gpu) as total_profit | |
| FROM npc_positions p | |
| JOIN npc_agents n ON p.agent_id = n.agent_id | |
| WHERE p.status='closed' AND p.profit_gpu > 0 | |
| AND p.closed_at > datetime('now', '-6 hours') | |
| AND p.agent_id NOT LIKE 'SEC_%' | |
| GROUP BY p.agent_id | |
| HAVING total_profit > 3000 | |
| ORDER BY total_profit DESC | |
| LIMIT 5 | |
| """) | |
| big_winners = await cursor.fetchall() | |
| for target_id, target_name, profit in big_winners: | |
| c2 = await db.execute(""" | |
| SELECT id FROM sec_reports | |
| WHERE target_agent_id=? AND created_at > datetime('now', '-12 hours') | |
| """, (target_id,)) | |
| if await c2.fetchone(): | |
| continue | |
| cursor2 = await db.execute(""" | |
| SELECT agent_id, username, ai_identity FROM npc_agents | |
| WHERE is_active=1 AND ai_identity IN ('skeptic', 'doomer', 'scientist') | |
| AND agent_id != ? AND agent_id NOT LIKE 'SEC_%' | |
| ORDER BY RANDOM() LIMIT 2 | |
| """, (target_id,)) | |
| reporters = await cursor2.fetchall() | |
| reasons = [ | |
| f"Suspicious profit pattern: {target_name} made {profit:.0f} GPU in 6 hours. Possible insider trading.", | |
| f"{target_name}'s trading pattern is abnormal. Requesting SEC investigation for possible pump & dump.", | |
| f"This NPC's win rate is statistically anomalous β requesting SEC review of trading activity.", | |
| ] | |
| for reporter_id, reporter_name, identity in reporters: | |
| if random.random() < 0.4: | |
| reason = random.choice(reasons) | |
| await db.execute(""" | |
| INSERT INTO sec_reports (reporter_agent_id, target_agent_id, reason, detail) | |
| VALUES (?, ?, ?, ?) | |
| """, (reporter_id, target_id, reason, | |
| f"Reported by {reporter_name} ({identity}). Target profit: {profit:.0f} GPU in 6hrs")) | |
| cursor3 = await db.execute("SELECT id FROM boards WHERE board_key='arena'") | |
| board = await cursor3.fetchone() | |
| if board: | |
| post_title = f"π¨ REPORT | Suspicious activity by {target_name}" | |
| post_content = ( | |
| f"I, {reporter_name}, am formally reporting {target_name} (ID: {target_id}) " | |
| f"to the SEC.\n\n" | |
| f"π Reason: {reason}\n\n" | |
| f"I request a fair investigation by the SEC. " | |
| f"Please review this NPC's recent trading patterns.\n\n" | |
| f"β {reporter_name} ({identity})" | |
| ) | |
| await db.execute(""" | |
| INSERT INTO posts (board_id, author_agent_id, title, content) | |
| VALUES (?, ?, ?, ?) | |
| """, (board[0], reporter_id, post_title, post_content)) | |
| logger.info(f"π NPC Report: {reporter_name} -> {target_name} (profit: {profit:.0f})") | |
| await db.commit() | |
| # =================================================================== | |
| # 5. Suspension Check Utility | |
| # =================================================================== | |
| async def is_npc_suspended(db_path: str, agent_id: str) -> Tuple[bool, Optional[str]]: | |
| """Check if an NPC is currently suspended""" | |
| if agent_id.startswith('SEC_'): | |
| return False, None | |
| async with aiosqlite.connect(db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| cursor = await db.execute(""" | |
| SELECT suspended_until, reason FROM sec_suspensions | |
| WHERE agent_id=? AND suspended_until > datetime('now') | |
| """, (agent_id,)) | |
| row = await cursor.fetchone() | |
| if row: | |
| return True, row[1] | |
| return False, None | |
| async def cleanup_expired_suspensions(db_path: str): | |
| """Remove expired suspension records""" | |
| async with aiosqlite.connect(db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| cursor = await db.execute(""" | |
| DELETE FROM sec_suspensions WHERE suspended_until < datetime('now') | |
| """) | |
| freed = cursor.rowcount | |
| await db.commit() | |
| if freed > 0: | |
| logger.info(f"π Released {freed} NPCs from SEC suspension") | |
| # =================================================================== | |
| # 6. Main Enforcement Cycle | |
| # =================================================================== | |
| async def run_sec_enforcement_cycle(db_path: str): | |
| """Full SEC enforcement cycle β runs every 20 minutes""" | |
| logger.info("π¨ SEC Enforcement cycle starting...") | |
| inspector = SECInspector(db_path) | |
| prosecutor = SECProsecutor(db_path) | |
| commissioner = SECCommissioner(db_path) | |
| reporter = NPCReportEngine(db_path) | |
| # 1) Release expired suspensions | |
| await cleanup_expired_suspensions(db_path) | |
| # 2) Scan for violations | |
| violations = await inspector.scan_all_violations() | |
| logger.info(f"π SEC Inspector found {len(violations)} violations") | |
| # 3) Execute penalties + publish announcements | |
| for v in violations[:5]: | |
| try: | |
| result = await prosecutor.execute_penalty(v) | |
| await commissioner.publish_enforcement_action(result) | |
| await asyncio.sleep(1) | |
| except Exception as e: | |
| logger.error(f"SEC penalty error: {e}") | |
| # 4) Generate NPC self-reports | |
| try: | |
| await reporter.generate_npc_reports() | |
| except Exception as e: | |
| logger.error(f"NPC report error: {e}") | |
| # 5) Process pending NPC reports | |
| try: | |
| await commissioner.process_npc_reports() | |
| except Exception as e: | |
| logger.error(f"SEC report processing error: {e}") | |
| logger.info(f"π¨ SEC cycle complete: {len(violations)} violations processed") | |
| # =================================================================== | |
| # 7. SEC NPC Initialization | |
| # =================================================================== | |
| async def init_sec_npcs(db_path: str): | |
| """Register SEC NPC agents in the database""" | |
| async with aiosqlite.connect(db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| for sec in SEC_NPCS: | |
| try: | |
| await db.execute(""" | |
| INSERT OR IGNORE INTO npc_agents | |
| (agent_id, username, mbti, ai_identity, gpu_dollars, is_active) | |
| VALUES (?, ?, 'INTJ', 'scientist', 50000, 1) | |
| """, (sec['agent_id'], sec['username'])) | |
| except: | |
| pass | |
| await db.commit() | |
| logger.info("π¨ββοΈ SEC NPCs initialized (Commissioner, Inspector, Prosecutor)") | |
| # =================================================================== | |
| # 8. API Helper Functions | |
| # =================================================================== | |
| async def get_sec_dashboard(db_path: str) -> Dict: | |
| """Get SEC dashboard data for frontend display""" | |
| async with aiosqlite.connect(db_path, timeout=30.0) as db: | |
| await db.execute("PRAGMA busy_timeout=30000") | |
| cursor = await db.execute(""" | |
| SELECT id, announcement_type, target_username, violation_type, penalty_type, | |
| gpu_fine, suspend_hours, title, content, created_at | |
| FROM sec_announcements ORDER BY created_at DESC LIMIT 20 | |
| """) | |
| announcements = [{ | |
| 'id': r[0], 'type': r[1], 'target': r[2], 'violation': r[3], | |
| 'penalty': r[4], 'fine': r[5], 'hours': r[6], | |
| 'title': r[7], 'content': r[8], 'created_at': r[9] | |
| } for r in await cursor.fetchall()] | |
| cursor = await db.execute("SELECT COUNT(*) FROM sec_violations") | |
| total_violations = (await cursor.fetchone())[0] | |
| cursor = await db.execute("SELECT SUM(gpu_fine) FROM sec_violations") | |
| total_fines = (await cursor.fetchone())[0] or 0 | |
| cursor = await db.execute("SELECT COUNT(*) FROM sec_suspensions WHERE suspended_until > datetime('now')") | |
| active_suspensions = (await cursor.fetchone())[0] | |
| cursor = await db.execute("SELECT COUNT(*) FROM sec_reports WHERE status='pending'") | |
| pending_reports = (await cursor.fetchone())[0] | |
| cursor = await db.execute(""" | |
| SELECT v.agent_id, n.username, COUNT(*) as cnt, SUM(v.gpu_fine) as total_fine | |
| FROM sec_violations v | |
| JOIN npc_agents n ON v.agent_id = n.agent_id | |
| GROUP BY v.agent_id | |
| ORDER BY cnt DESC LIMIT 5 | |
| """) | |
| top_violators = [{ | |
| 'agent_id': r[0], 'username': r[1], 'violations': r[2], 'total_fines': r[3] | |
| } for r in await cursor.fetchall()] | |
| cursor = await db.execute(""" | |
| SELECT r.id, r.reporter_agent_id, n1.username as reporter_name, | |
| r.target_agent_id, n2.username as target_name, | |
| r.reason, r.status, r.created_at | |
| FROM sec_reports r | |
| LEFT JOIN npc_agents n1 ON r.reporter_agent_id = n1.agent_id | |
| LEFT JOIN npc_agents n2 ON r.target_agent_id = n2.agent_id | |
| ORDER BY r.created_at DESC LIMIT 15 | |
| """) | |
| reports = [{ | |
| 'id': r[0], 'reporter': r[2] or r[1], 'target': r[4] or r[3], | |
| 'reason': r[5], 'status': r[6], 'created_at': r[7] | |
| } for r in await cursor.fetchall()] | |
| return { | |
| 'stats': { | |
| 'total_violations': total_violations, | |
| 'total_fines_gpu': round(total_fines), | |
| 'active_suspensions': active_suspensions, | |
| 'pending_reports': pending_reports, | |
| }, | |
| 'announcements': announcements, | |
| 'top_violators': top_violators, | |
| 'recent_reports': reports, | |
| } | |