Skip to content

Enhanced AI Intelligence (storage layer behind ARIA's chat/recommendation routes)

Status: 🚧 Partial. All six tables are migrated (Re-verified 2026-08-21 vs origin/feat 46bce720.) (alembic/versions/c138b33baec4_initial_schema_with_stations_terminology.py) and the service that owns them (EnhancedAIService) is the live implementation behind POST /api/v1/ai/chat, POST /api/v1/ai/recommendations, GET /api/v1/ai/assistant/status, PUT /api/v1/ai/assistant/config, POST /api/v1/ai/learning/record-action, GET /api/v1/ai/analytics/performance, and POST /api/v1/ai/system/cleanup (services/gameserver/src/api/routes/enhanced_ai.py), plus the WebSocket aria_chat path (websocket_service.handle_aria_chat, services/gameserver/src/services/websocket_service.py:1372-1483). Every one of the six models has at least one live write path traced below — none is orphaned. This doc did not previously exist; the routes/service were documented in ../OPERATIONS/aria.md §2/§Architecture and ../SYSTEMS/aria-dialogue.md, but the storage layer they actually read/write (this file's six tables) was never named — a real doc gap, closed here.

Relationship to the ARIA personal-intelligence models — read this first

This is not the same storage layer documented in OPERATIONS/aria.md §2 ("Models") or DATA_MODELS/aria-data-index.md. That doc describes models/aria_personal_intelligence.py (ARIAPersonalMemory, ARIAMarketIntelligence, ARIAExplorationMap, ARIATradingObservation, ARIASecurityLog, ARIAQuantumCache) and its owning service, aria_personal_intelligence_service.py.

The six tables covered here live in a separate module (models/enhanced_ai_models.py) owned by a separate service (services/enhanced_ai_service.py, class EnhancedAIService). Verified by direct read: enhanced_ai_service.py imports only from src.models.enhanced_ai_models (enhanced_ai_service.py:39-43) and never imports or references aria_personal_intelligence.py or any of its five model classes anywhere in its ~1,666 lines (grep -n "aria_personal_intelligence\|ARIAPersonalMemory\|ARIATradingObservation\|ARIAExplorationMap\|ARIAMarketIntelligence\|ARIASecurityLog" enhanced_ai_service.py returns only a code-comment reference to the sibling service's naming convention, at line 1421 — no import, no call).

So the practical picture is: two disjoint persistence layers sit behind the single player-facing "ARIA" brand, both live simultaneously on the same request paths in places:

  • POST /api/v1/ai/chatEnhancedAIService.process_natural_language_query → reads/writes this file's tables (ai_comprehensive_assistants, ai_conversation_logs, ai_cross_system_knowledge, ai_security_audit_log). It does not touch aria_personal_intelligence.py's tables directly, though it does call into ai_trading_service.py, market_prediction_engine.py, and route_optimizer.py (enhanced_ai_service.py:35-37) for its recommendation content, and those in turn may read the personal-intelligence tables (outside the scope of this doc; see aria-dialogue.md).
  • aria_personal_intelligence_service.py (the pipeline aria-dialogue.md documents in detail — prompt context assembly, encrypted memory, exploration map, trading observations) is a separate, unrelated write path with its own migration (6838b5cb335e_*.py) and its own Player relationships (aria_memories, aria_market_intelligence, aria_exploration_map, aria_trading_observations).

Neither doc's existing prose claims these are the same system, but neither previously named this file's tables at all — a reader following OPERATIONS/aria.md §2's "Models" table would reasonably conclude aria_personal_intelligence.py is the only persistence layer behind ARIA's chat surface. It is not. This is a parallel system, not a superset or an evolution of the personal-intelligence models — the module docstring's framing ("Building on existing ARIA foundation," enhanced_ai_models.py:2-3, enhanced_ai_service.py:2-3) describes an intent to extend ARIA's trading-AI foundation conceptually, not a literal build-on-top of the personal-intelligence tables at the schema level.

The six tables

All defined in services/gameserver/src/models/enhanced_ai_models.py.

AIComprehensiveAssistant (ai_comprehensive_assistants, enhanced_ai_models.py:62-201)

The per-player enhanced-assistant row — one per Player (player_id is unique=True, cascade-deleted with the player; Player.ai_assistant relationship, player.py:259). Holds assistant config (assistant_name, personality_type, learning_mode), a security_level (basic/standard/premium/enterprise), per-system access_permissions JSONB (trading/combat/colony/station booleans — a code comment at enhanced_ai_models.py:80-81 clarifies these gate advisory read access by default; action-taking gates live elsewhere), and a daily API quota (api_request_quota/api_requests_used/quota_reset_date) enforced by check_rate_limit(). Lazily created on first authenticated use: EnhancedAIService._validate_and_authenticate (enhanced_ai_service.py:213-236) selects-or-creates this row for every /ai/* call and every WS aria_chat message.

AICrossSystemKnowledge (ai_cross_system_knowledge, enhanced_ai_models.py:204-352)

Knowledge observations tagged by knowledge_domain (trading/combat/colony/station/strategic/social), with a security_classification and data_sensitivity pair, a JSONB payload (64KB cap, enforced in validates('knowledge_data')), and a confidence score that self-adjusts via update_confidence(). Written from EnhancedAIService at enhanced_ai_service.py:1453 (inside the natural-language query path). An ORM after_insert mapper event (enhanced_ai_models.py:849-891) automatically writes an AISecurityAuditLog row whenever a restricted/confidential or high/critical-sensitivity knowledge row is inserted — this fires unconditionally on matching inserts, independent of any route code remembering to call it.

AIStrategicRecommendation (ai_strategic_recommendations, enhanced_ai_models.py:355-534)

One row per recommendation surfaced to a player — category (trading/combat/colony/station/strategic/resource), a risk assessment, expected_outcome/actual_outcome JSONB pair, and user-response + outcome-accuracy tracking (record_outcome() computes accuracy once an actual outcome is recorded). EnhancedAIService.get_ai_performance_metrics (enhanced_ai_service.py:1559-1581) aggregates COUNT/AVG(outcome_accuracy)/AVG(user_feedback_score) over this table per-assistant — the source of the analytics returned by GET /api/v1/ai/analytics/performance.

AILearningPattern (ai_learning_patterns, enhanced_ai_models.py:537-641)

Versioned, named behavioral/market/tactical/strategic/social patterns the assistant has "learned," each with a confidence score, validation_attempts/successful_validations counters (success_rate hybrid property), and an is_active/deactivated_reason lifecycle pair. AILearningPattern.assistant_id + AILearningPattern.is_active is queried in the same performance-metrics aggregate above (enhanced_ai_service.py:1577-1581). No direct grep hit was found for a route or service method that inserts a new AILearningPattern row today — POST /ai/learning/record-action (enhanced_ai_service.py:1437 record_player_action) records a raw player action, not a discovered pattern; whether pattern discovery (as opposed to pattern counting) is implemented elsewhere was not confirmed in this pass and should be treated as an open question, not an assumed gap.

AIConversationLog (ai_conversation_logs, enhanced_ai_models.py:644-773)

GDPR-flavored conversation history: sanitized input/response text (with length caps enforced in validates), a data_retention_days field (30-2555 day bound) driving the expires_at/is_expired hybrid properties, and hashed (not raw) IP/user-agent fields. Written at enhanced_ai_service.py:1386 inside every conversational turn. POST /api/v1/ai/system/cleanupEnhancedAIService.cleanup_expired_data (enhanced_ai_service.py:1515-...) is the GDPR-retention sweep referenced in this table's docstring; the route comment (enhanced_ai.py, System Maintenance section) notes admin-gating is not actually enforced yet — "any authenticated user can trigger cleanup for their own data" is a literal code comment, not a documented access-control guarantee.

AISecurityAuditLog (ai_security_audit_log, enhanced_ai_models.py:775-846)

The audit trail for this module — event_type (access/data_access/recommendation/pattern_learning/security_violation/quota_exceeded), severity_level, free-text event_description (1000-char cap), and investigation-workflow fields. Written explicitly by EnhancedAIService (e.g. enhanced_ai_service.py:384, :1640) and automatically by the AICrossSystemKnowledge after_insert listener described above. assistant_id/player_id foreign keys are ondelete="SET NULL" — audit rows outlive the assistant/player they reference, by design.

Wired vs dormant — verified via grep

Wired (live, reachable from a real request path): - All six model classes are imported and constructed/queried by EnhancedAIService (services/gameserver/src/services/enhanced_ai_service.py). - EnhancedAIService is instantiated from api/routes/enhanced_ai.py at every one of its 9 endpoint handlers (grep -n "ai_service = EnhancedAIService(db)" enhanced_ai.py → 8 distinct call sites at lines 312/387/501/574/623/698/741/779), and the router is mounted: src/api/api.py:21 imports it, src/api/api.py:112 calls api_router.include_router(enhanced_ai_router, tags=["enhanced-ai"]). - EnhancedAIService is also instantiated directly from websocket_service.py:1477 inside handle_aria_chat, so the WebSocket aria_chat command path bypasses the REST router but hits the identical service method (process_natural_language_query) — the same code comment at websocket_service.py:1376-1382 states this explicitly ("the same proven path the /enhanced-ai/chat REST route uses; we do not bypass it"). - enhanced_websocket_service.py:729 also constructs an EnhancedAIService(aria_db) — a second WS-adjacent call site, not audited further in this pass. - Player.ai_assistant relationship (player.py:259) and cascade-delete are live at the ORM level (used by _validate_and_authenticate's select).

Not confirmed wired / open questions: - No frontend (player-client/src, admin-ui/src) call site was found for any /ai/recommendations, /ai/chat, /ai/assistant/status, /ai/learning/record-action, or /ai/analytics/performance path string (grep -rl across both frontends returned zero matches). The WebSocket aria_chat command path is the one confirmed frontend-reachable entry, per websocket.ts. Whether the REST /ai/* endpoints have any current caller (frontend, admin tooling, or otherwise) beyond direct API testing was not established here — flagged as an open question, not asserted dormant, since a caller could exist outside the two frontend trees searched (mobile client, external tooling, curl-based ops scripts). - AILearningPattern insertion path — see note under that table above. - POST /ai/system/cleanup admin-gating is a literal known gap per the route's own code comment, not a doc invention.

Security / GDPR design notes (load-bearing, not decorative)

The module docstring (enhanced_ai_models.py:1-13) advertises OWASP-aligned controls; the following are genuinely present in code, not aspirational:

  • Input sanitization at the ORM layer. @validates hooks on AIComprehensiveAssistant.assistant_name, AIStrategicRecommendation.recommendation_summary/user_feedback_text, AILearningPattern.pattern_description, and AIConversationLog.user_input_sanitized/ai_response_text all strip HTML tags and `<>"'`` characters and enforce hard length caps before the value ever reaches the database — independent of whatever sanitization happens earlier in the request pipeline.
  • JSONB size caps. AICrossSystemKnowledge.knowledge_data (64KB), .source_metadata (4KB), AIStrategicRecommendation.detailed_analysis (32KB) / .expected_outcome/.actual_outcome (16KB) are all enforced in @validates, raising ValueError past the limit — a real defense against unbounded JSONB bloat, not just a comment.
  • Hashed, not raw, network identifiers. AIConversationLog.ip_address_hash/user_agent_hash and AISecurityAuditLog.ip_address_hash/user_agent_hash store SHA-256 hashes (AIConversationLog.hash_sensitive_data, enhanced_ai_models.py:767-772), never the raw IP/UA string.
  • GDPR retention window. AIConversationLog.data_retention_days is CHECK-constrained to 30-2555 days (enhanced_ai_models.py:704-706) and drives expires_at; EnhancedAIService.cleanup_expired_data is the sweep that acts on it, invoked via POST /api/v1/ai/system/cleanup — but see the admin-gating gap noted above.
  • Automatic sensitive-write audit. The AICrossSystemKnowledge after_insert mapper-level event listener (enhanced_ai_models.py:849-891) is a defense-in-depth control that does not depend on service-layer code remembering to log — it fires inside the same transaction as the triggering INSERT via the raw Core connection, per the docstring explaining why a mapper event (not a second ORM session) is the correct pattern here.
  • Dangerous-key rejection. AICrossSystemKnowledge.validates('knowledge_data') explicitly rejects __proto__/constructor/prototype keys — a prototype-pollution-style guard, notable because this is a Python/SQLAlchemy JSONB column, not a JS object; it's a defensive habit carried over rather than a defense against a Python-native threat model.

References

  • Models: services/gameserver/src/models/enhanced_ai_models.py
  • Service: services/gameserver/src/services/enhanced_ai_service.py
  • Routes: services/gameserver/src/api/routes/enhanced_ai.py, mounted at services/gameserver/src/api/api.py:21,112
  • WebSocket caller: services/gameserver/src/services/websocket_service.py:1372-1483 (handle_aria_chat), services/gameserver/src/services/enhanced_websocket_service.py:729
  • Migration: services/gameserver/alembic/versions/c138b33baec4_initial_schema_with_stations_terminology.py
  • Sibling/parallel system (separate storage, same player-facing brand): OPERATIONS/aria.md, SYSTEMS/aria-dialogue.md, services/gameserver/src/models/aria_personal_intelligence.py, services/gameserver/src/services/aria_personal_intelligence_service.py