Spaces:
Running
Running
File size: 42,808 Bytes
db06ad2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 | """
π¨ 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,
}
|