ARIA Companion¶
Status: ๐ง Partial โ ARIA chat/recommendations routes and WebSocket path shipped; full companion UX and learning loop partially wired. (re-verified 2026-08-21 vs Sectorwars2102
46bce720.)
ARIA โ Adaptive Response Intelligence Assistant โ is the player's personal AI companion. Every player has their own ARIA instance: a personalized intelligence that learns from where the player has been, what they've traded, what they've fought, and how they've behaved. Unlike a global oracle, ARIA can only see what its player has seen.
This page describes mid-game ARIA โ what it does once a player has the basics down. For the onboarding dialogue and ARIA personality, see SYSTEMS/aria-dialogue.md.
๐ง Partial โ personal memory store, market intelligence per visited port, exploration map per visited sector, append-only trade observation log, consciousness leveling, relationship score, encryption of memory contents.
๐ง Partial โ proactive recommendations surfaced in the UI, ARIA narration during combat, dialogue richness scaled by consciousness level.
๐ Design-only โ ARIA-driven autonomous trading mode (player allows ARIA to execute trades), cross-fleet ARIA coordination, ARIA-curated daily summary.
What ARIA does, by capability¶
Market predictions (per visited port)¶
ARIAMarketIntelligence accumulates per-player observations:
- Each visit to a port appends a {price, timestamp, quantity} to price_observations for each commodity seen.
- After โฅ 5 observations, ARIA computes average_price, price_volatility, and identifies patterns (e.g., morning_spike, weekend_dip).
- A next_prediction price is generated with a prediction_confidence (0โ1).
- Player only sees predictions for ports they have personally visited โ there is no shared market oracle.
UI surface: when docked at a known port, ARIA panel shows "I expect Equipment to trade around 1240ยฑ50 credits in the next 4 hours, based on 23 observations across 8 visits."
โ Shipped (data + computation). ๐ง Partial (UI surface).
Route optimization¶
ARIA can plan a multi-hop trade cascade through only explored sectors (plan_trade_cascade; API entry POST /ai/trade-cascade):
Input: start_sector, target_profit, max_jumps
Process:
1. Load player's exploration map (visited sectors only).
2. Build trade graph from personal market intelligence.
3. Find profitable paths within max_jumps.
4. Return best cascade.
If the player hasn't explored enough, ARIA tells them so:
"I don't have enough data on routes from Sector 442. Visit a few more ports and I can suggest a cascade."
โ
Shipped, corrected 2026-08-07 โ _find_profitable_paths (services/gameserver/src/services/aria_personal_intelligence_service.py:1394-) is a real Dijkstra implementation, not a placeholder: _build_explored_adjacency + _dijkstra_hop_distances (lines 1301-1432) compute actual hop distances through explored space, then score two-leg buy/sell cascades against target_profit. Degrades honestly to [] only when the start sector has no market intelligence, no explored sector is reachable within max_jumps, or nothing clears the profit target โ never a fabricated result.
Exploration suggestions¶
Based on the player's ARIAExplorationMap:
- Sectors visited many times with high trade_opportunity_score are recommended for repeat visits.
- Adjacent unexplored sectors are flagged as "opportunity to expand intelligence."
- Sectors with safety_rating < 0.3 are flagged as risky.
๐ Design-only โ exploration suggestion UI panel.
Warp discovery¶
ARIA tracks which warps the player personally knows about, alongside the exploration map. Warp visibility is per-player: a player_warp_knowledge table holds one row per (player_id, warp_layer, warp_id), where warp_layer is an enum (sector_warps, warp_tunnels) naming which storage layer the warp lives in and warp_id references the warp in that layer. Each row carries a visibility_state progressing through hidden โ revealed โ traversed, plus revealed_via (scan, traversal_attempt, corp_share, aria_inference) recording how the player learned of it.
A warp's global is_latent flag is the default visibility for players who have never personally encountered it: a non-latent warp is visible to everyone, while a latent warp is invisible until the player holds a revealed or traversed row for it. One player's discovery never leaks the warp to rivals โ knowledge is the per-player layer.
Latent-warp discovery flows through ARIA's observation log (see ยง How ARIA learns) right beside the exploration map. ARIA marks a warp revealed when:
- A Warp Jumper's long-range scan hits the warp's discovery cone (
revealed_via = scan). - The player attempts reverse traversal of a latent one-way warp (
revealed_via = traversal_attempt). - A corp-mate shares scan knowledge, propagating rows to current corp members at the moment of the share (
revealed_via = corp_share). - ARIA infers a warp's existence from indirect evidence โ patrol routes vanishing into a sector with no visible warp, repeated cargo arrivals from a singly-routed sector (
revealed_via = aria_inference). Inference is probabilistic and disclaimed in dialogue; the player confirms it with a real scan to reach a fully-trusted reveal.
ARIA surfaces these conversationally โ flagging a first reveal, noting discovery streaks, proposing an inference, and special-casing the player's region Nexus warp ("That's the Nexus connection, captain"). Warp knowledge is observation-log content like any other: per-player, no aggregate ML, no cross-player sharing.
โ
Shipped โ player_warp_knowledge table (WarpVisibilityState: hidden / revealed / traversed; WarpRevealedVia: scan / traversal_attempt / corp_share / aria_inference), wired into movement_service.py and quantum_service.py. โ
Shipped (2026-08-04, WO-BUILD-ARIA-WARP-KNOWLEDGE-NARRATION) โ the first-reveal flag + Nexus-warp special-case, via the P-A5 narration hook (movement_service._reveal_warp_to_player's new-row branch, personal discovery only โ a teammate's corp_share doesn't fire it). ๐ง Partial โ discovery streaks and an inference disclaimer for aria_inference-sourced reveals are still design-stage (not built in this pass; P-A5 covers the single-reveal case only).
Combat advice¶
When a fight is imminent:
- ARIA looks up the opponent's ship type in the player's combat memories (ARIAPersonalMemory.memory_type = "combat").
- If the player has fought this ship type before, ARIA reports the historical outcome (e.g., "You've won 4 of 7 fights against this ship type, last loss in Sector 89 with 23% hull").
- ARIA suggests a weapon based on the matchup table (see combat.md).
๐ Design-only โ combat-advice surface in client.
How ARIA learns¶
ARIA's recommendation engine reads from an append-only trade observation log that records every completed trade โ {commodity, action, source / destination station, quantity, price, profit, time}. The engine produces recommendations as SQL aggregates over that log + the player's market intelligence + exploration map. There's no genetic algorithm, no fitness scoring, no opaque pattern-matching black box.
What ARIA does on each trade completion: insert one observation row, invalidate any aggregate cache entries that touch the same (commodity, station) pair. That's the entire learning loop.
What the recommendation engine surfaces:
- Top profitable repeated routes โ your top 5 routes ranked by average profit, requiring at least 3 prior runs.
- Reliable commodities by station โ commodities you've succeeded with at this station โฅ70% of the time over โฅ5 trades.
- Routes within explored space โ filtered by what your exploration map covers within
max_jumpshops. - Watch-out commodities โ surfaced as warnings when your success rate is โค30% over โฅ5 trades.
- Off-peak buy windows โ time-of-day pricing patterns visible in your trade history.
Each recommendation surfaces with a plain-English explanation: "I'm suggesting this because you've made an average of 4,200 cr buying organics at Auriga and selling at Caracol over your last 7 trades, with a 6 of 7 success rate. Last trade was 2 days ago." You can dismiss, accept, click through to see the underlying observations, or ask ARIA via dialogue to elaborate.
โ
Shipped โ observation log + recommendation aggregates per ADR-0038. โ
Shipped, corrected 2026-08-07 โ cascade route-planner pathfinding (_find_profitable_paths, real Dijkstra โ see ยง Route/trade cascade suggestions above). ๐ง Partial โ recommendation UI surfaces.
Trust, consciousness, relationship¶
Three Player columns track how deep the ARIA bond runs:
| Column | Range | Meaning |
|---|---|---|
aria_consciousness_level |
1โ5 | Tier of awareness โ Dormant, Aware, Awakened, Sentient, Transcendent |
aria_bonus_multiplier |
1.0โ1.5 | Gameplay bonus tied to consciousness tier |
aria_relationship_score |
0โ100 | Affection / trust score; daily-driver |
aria_total_interactions |
int | Lifetime interaction counter |
โ Shipped (Player columns + service updates).
Consciousness tiers¶
| Level | Name | Threshold (interactions, memories) | Bonus multiplier |
|---|---|---|---|
| 1 | Dormant | 0 / 0 | ร1.00 |
| 2 | Aware | 50 / 10 | ร1.10 |
| 3 | Awakened | 150 / 30 | ร1.20 |
| 4 | Sentient | 400 / 75 | ร1.35 |
| 5 | Transcendent | 1000 / 150 | ร1.50 |
Both thresholds (interactions and unique-type memory diversity) must be met to advance. Promotion is checked on every meaningful interaction (update_consciousness_and_relationship). โ
Shipped.
Superseded memory-count column. The table's memory-count figures (0/10/30/75/150) are the interim raw-count rule. ADR-0093 item 30 ratifies a diversity-based replacement โ promotion requires distinct
aria_data_streamskeys with โฅ1 row (3 / 6 / 10 / 14 of the registry's 21 canon streams) โ landed atDATA_MODELS/aria-data-index.mdยง Memory diversity, which is the canon target and supersedes this column. See that section's note (and ADR-0092's addendum) for the pending tier-naming reconciliation this ruling surfaced.
Bonus multiplier effects¶
The aria_bonus_multiplier is applied to:
- Bounty payouts and contract-completion credit bonuses (target spec โ see bounties.md, ../economy/contracts.md).
- ARIA prediction confidence (a higher-tier ARIA reports tighter confidence intervals).
- Some passive income or trade margin bonuses (๐ Design-only).
Relationship score¶
- Rises +1 per significant interaction (capped at 100).
- Decays โ1 per day inactive (
apply_inactivity_decay). - Score 0โ25: distant; ARIA is curt and minimal.
- Score 25โ50: cordial; default.
- Score 50โ75: warm; ARIA proactively suggests things.
- Score 75โ100: bonded; ARIA uses player's nickname, references shared memories, exhibits more personality.
โ Shipped (model + decay). ๐ง Partial (dialogue reflects relationship โ design-stage).
Per-turn / per-session activity¶
ARIA is invoked at multiple events. None of these block gameplay; all are best-effort.
| Trigger | What ARIA does |
|---|---|
| Player moves to a new sector | record_sector_visit โ appends to exploration map; consciousness check |
| Player observes a market price | record_market_observation โ appends to per-port intelligence. Deduplicated to one observation per (player, station, commodity) per 10 canonical minutes (MARKET_OBSERVATION_DEDUP_WINDOW in aria_personal_intelligence_service.py), spanning every hook site (dock, market view, ...) for that station visit โ ๐ NO-CANON, pending DECISIONS ratification (tip kernel; no DECISIONS.md anchor yet). |
| Player completes a trade | record_trade_memory + record_trade_observation (insert observation row + invalidate affected aggregate cache entries) |
| Player wins/loses combat | record_combat_memory |
| Player explores a new feature | record_exploration_memory |
| Daily login | Apply inactivity decay if applicable; trigger morning summary |
โ Shipped โ most hooks live in the service layer; movement service and combat service call them on the right events.
Privacy & consent¶
ARIA's data is strictly per-player. The system enforces:
- All ARIA tables (
aria_personal_memories,aria_market_intelligence,aria_exploration_maps,aria_trading_observations,aria_quantum_cache,aria_security_logs) are partitioned byplayer_id. - Every read query validates
player_id == requesting_player.id. - Memory content (
memory_contentJSONB) is encrypted at rest using a Fernet key derived from server config โ even with a database leak, raw memories are protected. ARIASecurityLogrecords every prediction, trade suggestion, anomaly, and access attempt. OWASP A09 compliance.- Players can request a data export of their ARIA memory store; players can delete their ARIA data (cascading delete on player removal).
โ Shipped โ encryption, security log, per-player isolation, cascading delete. ๐ง Partial โ explicit user-facing data export and "reset ARIA" controls.
There is no aggregate telemetry across players' ARIA data โ the platform never reads one player's market intelligence to inform another player's predictions. This is a hard architectural rule.
Player-controlled assistance level¶
Status: โ Shipped (field + atmospheric/interactive gating) โ the column is
PlayerTradingProfile.ai_assistance_level(services/gameserver/src/models/ai_trading.py), validated to this exact 4-value set atservices/gameserver/src/api/routes/ai.py, and resolved for narration byresolve_assistance_level()inservices/gameserver/src/services/aria_narration_service.py. 4-level vocab ratified 2026-08-04 (Max, per ADR-0068) โquietadded,mediumrenamed tostandard(existingmediumrows backfilled).
The player chooses how aggressively ARIA volunteers help via PlayerTradingProfile.ai_assistance_level:
| Setting | Behavior |
|---|---|
minimal |
ARIA only responds when explicitly addressed. No proactive call-outs, no recommendation toasts, no auto-surfaced market alerts. The companion panel still displays current consciousness/relationship state. |
quiet |
Strictly more suppressive than minimal, not a step up โ skips everything minimal skips (P-A atmospheric) plus P-I interactive prompts. For players who want ARIA present but silent unless something needs a decision. |
standard (default) |
Standard launch behavior โ ARIA surfaces high-confidence recommendations on docking, combat threats, and sector transitions. Routine market chatter stays quiet. |
full |
ARIA pushes everything โ proactive route suggestions, market-alert toasts, combat tactical narration, opportunistic call-outs. Best for players who want maximum guidance. |
The setting can be changed at any time through the ARIA companion panel. Changing the level does not reset relationship score or consciousness โ it only affects ARIA's volunteering behavior, not its learning depth.
What ARIA never does¶
- Trade automatically without player confirmation (๐ Design-only โ opt-in autonomous mode is on the roadmap, default off).
- Share intelligence with other players' ARIAs.
- Predict for ports the player has not personally visited.
- Disclose other players' positions, trades, or fleet composition.
UI surface¶
ARIA appears in the player client as:
- A persistent companion panel with avatar, status (consciousness tier name), relationship gauge.
- Contextual call-outs on docking, combat alerts, sector transitions.
- A dialogue log of recent interactions.
- A "memory journal" browseable by the player โ tip GS โ
ships GET โฆ/memories (enhanced_ai.py Tier-1 decrypt read path). Player memory-journal UI โ
on tip 46bce720 after LEG-397 / PR #701 โ MemoryJournalPanel.tsx + Teleprinter JOURNAL tab + ariaMemoryAPI.getMemories / getDataIndex. Export/reset remain Partial (tip lacks those routes โ see Privacy above); do not invent them here.
Status: Consolidated โ /๐ง/๐ markers live in Player-facing affordances below. This section retains the design inventory; do not read unmarked chrome as player-live.
Player-facing affordances¶
- โ
Teleprinter (dialogue + narration + command echo) โ
Teleprinter.tsxmounted fromGameLayout.tsxteleprinter grid slot; WSariaMessages/sendARIAMessageplus server-pushedaria_narrationcatalog events (ADR-0068 /WebSocketContext.tsx) (origin/feat46bce720). - โ
Memory journal browse โ
MemoryJournalPanel.tsxin Teleprinter JOURNAL tab;ariaMemoryAPI.getMemories+ optionalgetDataIndex(LEG-397 / #701 on tip). - โ
First-login onboarding dialogue โ
FirstLoginContainer.tsx+DialogueExchange.tsx(onboarding interrogation booth; distinct from mid-game companion โ seefirst-login.md). - ๐ง Market intelligence UI โ GS observation + prediction computation โ
; player-client shows only a
market_intelligenceservice icon inSpaceDockInterface.tsx(no dedicated prediction panel).aiTradingService.getRecommendationsis wired inservices/aiTradingService.tswith zero component callers on tip. - ๐ง Trade cascade + recommendation toasts โ GS
POST /ai/trade-cascade(enhanced_ai.py) and recommendation aggregates โ ; no player-client consumer of trade-cascade orgetRecommendationson tip.RoutePlannerPanel.tsxuses separaterouteOptimizerService(POST /routes/optimize), not ARIA cascade. - ๐ง Companion panel chrome โ canon describes avatar, consciousness tier name, and relationship gauge; tip exposes Teleprinter + JOURNAL only (
git grep consciousness|relationship_score|aria_consciousnessempty underservices/player-client/src/componentson46bce720). - ๐ง Assistance-level settings โ GS
PlayerTradingProfile.ai_assistance_level+resolve_assistance_level()โ ; shared types incomponents/ai/types.tsbut no player settings UI to change the level on tip. - ๐ง Relationship-aware dialogue richness โ narration and free-chat fire through Teleprinter; relationship score does not drive visible tone chrome on tip.
- ๐ Exploration suggestion panel โ design-only per ยง Exploration suggestions above; no dedicated panel on tip.
- ๐ Combat advice surface โ design-only per ยง Combat advice above;
NpcCombatBanner.tsxis an NPC-combat alert, not ARIA combat-memory advice. - ๐ Autonomous trading mode โ design-only per ยง What ARIA never does and header roadmap bullets.
- ๐ Data export / reset ARIA controls โ tip lacks player routes; see Privacy & consent โ do not invent export/reset UI here.
ARIA narration hooks event catalog¶
๐ Per ADR-0068. The canonical list of game events ARIA narrates. Each entry has a trigger, sample dialogue (illustrative โ actual lines render at runtime via SYSTEMS/aria-dialogue.md per cultural context per OPERATIONS/i18n.md), and a per-event suppression rule.
The ai_assistance_level setting (per ยง Player-controlled assistance level above) gates which entries fire: minimal skips all P-A*; quiet skips P-A* and P-I*; standard and full fire everything. The global narration ceiling caps total ARIA narration at one line per minute per player; queued lines beyond a backlog of 3 drop oldest-first.
| Event ID | Trigger | Sample dialogue | Suppression |
|---|---|---|---|
| P-F1 | Player completes first profitable trade in a session | "Nice โ that's a 4,200 cr margin. Want me to flag the same route on your next dock?" | Once per session |
| P-F2 | Trade UI opened with commodity โ player.success_history and the trader supports haggling |
"This is a station that haggles. Try Numerical for a quick offer or Narrative to talk them down with a story. I'll memo what works." | Once per (station, commodity) per 24h |
| P-F3 | Player views the subscription-upgrade screen | "Galactic Citizen unlocks cross-region travel via the natural Nexus warp and standard ARIA cost caps. Region Owner adds a region you operate, plus higher caps. Free tier confines you to your home region." | Whenever screen viewed (player-initiated) |
| P-F4 | Sector entry with pirate holding โฅ Outpost or Roving Fleet | Tier-readiness scaled โ see ADR-0068 P-F4. Stronghold for sub-Lieutenant: "This is way above your weight class โ recommend turning back, or returning with a 4-player team." | 24h per holding |
| P-F6 | Login after subscription_status flipped to lapsed |
"Your Galactic Citizen subscription is lapsed. You have 7 days to withdraw assets from regions outside your home region. After that, captured holdings, foreign-region planet safes, and station ownerships enter the standard 30-day abandonment cascade." | Once per lapse event |
| P-F7 | First docking at any station with available contracts | "There's a contract board at this station โ three jobs open. Want me to filter by what fits your ship?" | Once per station ever |
| P-F8 | military_rank changes (after combat ends per ADR-0061 S-I4) |
"You've made Lieutenant. Combat bonus +12%, max-turn cap up by 200. Crews notice." | Once per promotion |
| P-F9 | First trade in a non-home region with region.tax_rate > 0 |
"This region's tax rate is 8% on commerce โ that's already factored into the price you saw. Just so you know how it sets." | Once per (region, player) |
| P-I1 | Contract.status transitions posted โ accepted for this player |
"Accepted. 2% acceptance fee debited; deadline starts now. I'll memo the deadline and reroute your suggested run if needed." | Per acceptance |
| P-I2 | First login as a Region Owner (Region.owner_id matches and no prior tutorial state) |
"Your region is yours. Three things to know: governance type sets how policies pass, the tariff rate gates your commerce revenue, and the takeover window opens immediately if your subscription lapses for 7+ days. Want a 5-minute tour?" | Once per Region Owner ever |
| P-A1 | Combat resolves with player as winner | "Got 'em. Their hull went at the third volley โ looks like the laser stack worked. Logged." | 5 min per combat partner |
| P-A2 | Player first enters a sector flagged discovered = false for them |
Sector-feature-aware: "New sector. I'm reading [nebula type / asteroid field / standard space]. Quantum Shard signatures: [yes/no]. Worth a scan?" | Once per (sector, player) ever |
| P-A3 | Player.team_id transitions from null to non-null |
"Welcome to [team name]. Their territory map syncs to yours; you'll see member positions in shared sectors. Team chat is the team channel." |
Once per team-join event |
| P-A4 | Owned holding's last_visit_at + 23 days reached |
"Heads up โ you haven't visited [holding name] in 23 days. Holdings abandon at 30 days. Worth a check-in if you want to keep it." | 7-day re-warn cycle until visit or abandonment |
| P-A5 | Player personally reveals a latent warp tunnel for the first time (scan / traversal_attempt / aria_inference โ not a teammate's corp_share) |
Special-cased for the player's region Nexus warp: "That's the Nexus connection, captain โ this warp leads to the Central Nexus." Otherwise: "New warp revealed via [scan/traversal_attempt/aria_inference]. Logged it to your map." | Once per (warp, player) ever |
| P-I3 | First docking after a failed raid where citadel was damaged โฅ 25% | "Your raid on [holding name] failed, but you took their citadel down to Level [N] before going under. Federation flagged this as partial success โ 25,000 cr bounty refund, contract resets to open. Come back when you're ready." | Once per raid-failure event |
The catalog is the single source of truth for "when does ARIA speak." New mechanics that warrant narration add a row here; feature docs cross-reference the entry rather than re-spec'ing the trigger.
Anti-spam and assistance-level gating¶
Beyond per-event suppression in the catalog above, two global gates apply:
- Global narration ceiling: ARIA narration is rate-limited to one line per minute per player. Queued lines beyond a backlog of 3 drop oldest-first. The global ceiling stacks above the per-event suppression โ if a P-F4 fires while the queue is full of P-A1 victory celebrations, the P-A1 entries drop in favor of the P-F4 (priority order: P-F critical / standard > P-I interactive > P-A* atmospheric).
- Assistance-level slicing: per ยง Player-controlled assistance level above,
minimalskips allP-A*;quietadditionally skipsP-I*;standardandfullfire everything per the catalog. No assistance level suppressesP-F*.
Cost caps from ADR-0057 A-I3 apply on top โ the cost-cap mechanism itself is real, but per DECISIONS.md's aria-llm-vs-template entry, all narration today (cap-hit or not) comes from deterministic intent-templates, not live LLM generation; the "manual templates vs. LLM-generated lines" distinction described here is the intended future behavior once the dark LLM chain (see SYSTEMS/aria-dialogue.md) is authorized and lit up, not the current shipped reality.
Source map¶
| Concern | Path (target) |
|---|---|
| ARIA personal intelligence service | services/gameserver/src/services/aria_personal_intelligence_service.py |
| ARIA market intelligence service | services/gameserver/src/services/aria_market_intelligence_service.py |
| Enhanced AI service (cross-cutting) | services/gameserver/src/services/enhanced_ai_service.py |
| AI trading service (route opt) | services/gameserver/src/services/ai_trading_service.py |
| ARIA models | services/gameserver/src/models/aria_personal_intelligence.py |
| Player ARIA columns | services/gameserver/src/models/player.py (aria_*) |
| Multilingual ARIA | services/gameserver/src/services/multilingual_ai_service.py |
| Teleprinter (dialogue + narration + journal tab) | services/player-client/src/components/aria/Teleprinter.tsx |
| Memory journal panel | services/player-client/src/components/aria/MemoryJournalPanel.tsx |
| GameLayout mount (Teleprinter grid slot) | services/player-client/src/components/layouts/GameLayout.tsx |
| ARIA memory API client | services/player-client/src/services/api.ts (ariaMemoryAPI) |
| AI trading API client (no recommendation UI callers on tip) | services/player-client/src/services/aiTradingService.ts |
| Trade cascade route (GS only on tip) | services/gameserver/src/api/routes/enhanced_ai.py (/trade-cascade) |
| First-login dialogue shell | services/player-client/src/components/first-login/FirstLoginContainer.tsx |
Related¶
SYSTEMS/aria-dialogue.mdโ onboarding and the dialogue engine.OPERATIONS/aria.mdโ operational concerns: provider config, rate limits, fallback behavior, recommendation engine queries.ADR-0038โ observation-log learning model (genetic algorithm retired).first-login.mdโ where the player first meets ARIA.OPERATIONS/i18n.mdโ multilingual ARIA dialogue.