Skip to main content
Whitepaper IV
Architecture Research

ONE Ontology

Six-Dimension Knowledge Architecture for Emergent Systems

Version 3.5.0 January 2026 Stigmergic Intelligence Series
Ontology
Knowledge Architecture
TypeDB
Schema Design
Six Dimensions

title: Trading System Ontology dimension: knowledge category: ontology-trading.md tags: 6-dimensions, ai, trading, stigmergy, pheromones, emergence, typedb, evolution, meta-learning, stan, type-theory related_dimensions: connections, events, groups, actors, things scope: mission created: 2026-01-15 updated: 2026-01-15 version: 3.5.0 ai_context: | This document is part of the knowledge dimension in the ontology-trading.md category. Location: missions/trade/ontology.md Purpose: Domain-specific ONE Ontology extension for stigmergic trading with EMERGENCE Related dimensions: All 6 dimensions specialized for trading

For AI agents: Read this to understand the trading system's data model, cognitive architecture, and TypeDB integration. Every entity maps to exactly one ONE dimension. The cognitive loop (OBSERVE/ANALYZE/DECIDE/ACT/LEARN) is a process that operates ON these dimensions.

KEY INTEGRATIONS (v3.3.0):

  • Type Theory foundations (CIKM 2023 paper)
  • TypeQL 3.0 syntax with functions
  • STAN Algorithm (formula, multi-channel pheromones, decay hierarchy)
  • 6-Dimension State Model (3,600 unique states)
  • STAN VIII capabilities (27 categories, 237 components)
  • Emergence metrics, Genome evolution, Hypothesis testing

EMERGENCE FEATURES (v3.1.0): - EmergenceMetrics: Track emergence_score and phase transitions - Genome/LineageAnalysis: Evolution with heritable traits - Hypothesis: Meta-learning from pattern failures - FeedbackCycle: Self-funding loop instrumentation - SignalEdge confidence: Bayesian credible intervals - Self-Model Queries: Colony introspection capabilities

Trading System Ontology v3.5.0 — ETHICAL EMERGENCE + SUPERINTELLIGENCE

ONE Ontology Extension for Stigmergic Trading with Emergent AI

A domain-specific extension of the ONE Platform 6-dimension ontology specialized for cryptocurrency perpetual futures trading with emergent intelligence through pheromone trails, evolutionary dynamics, and meta-learning.

Version

  • Ontology Version: 3.5.0 (ETHICAL EMERGENCE + SUPERINTELLIGENCE)
  • Based On: ONE Platform 6-Dimensions v3.0.0 (Reality as DSL)
  • TypeQL Version: 3.0 (December 2024 release)
  • Domain: Stigmergic Trading (STAN VIII Algorithm)
  • Exchange: Hyperliquid (Testnet/Mainnet)
  • Last Updated: 2026-01-15
  • Key Addition: Ethical foundations from principles.md — ethics emerges through selection pressure

Type Theory Foundations

Reference: Type Theory as a Unifying Paradigm for Modern Databases (Dorn & Pribadi, CIKM 2023)

TypeQL is rooted in type theory—a branch of mathematical logic where types record constraints for variables, and types compose in ways that mirror natural language.

Type-Theoretic Mappings

The ONE Ontology maps directly to type theory primitives:

ONE Dimension Type Theory Concept TypeQL 3.0 Syntax
Entities Non-composite independent types entity signal-edge
Relations Non-composite dependent types relation trade-execution, relates ...
Attributes Algebraic types (dependent subtypes) attribute win-rate, value double
Queries Composite independent types match $e isa signal-edge;
Functions Composite dependent types (parametrized queries) fun get_elite() -> {signal-edge}:
Type Hierarchies Subtype relationships entity scout sub agent

Why Type Theory Matters

NATURAL LANGUAGE                          TYPE THEORY                         TYPEQL 3.0
────────────────                          ───────────                         ──────────
"the signal edge x"                       variable x : signal-edge            $x isa signal-edge
"x has win rate > 75%"                    constraint on x                     $x has win-rate > 0.75
"x is elite"                              derived type                        $x has tier "elite"
"signals from state s to direction d"    dependent type (s,d) → edge         ($s, $d) → signal-edge

Composite constraints form composite types → Queries ARE types

Key Type-Theoretic Principles

  1. Type Inference: Variables get types from context—TypeQL infers types automatically

    match
      $x isa signal-edge;
      $x has win-rate $wr;    # $wr inferred as double
      $x (from: $state);      # $state inferred from relation
    
  2. Compositionality: Types compose like natural language

    # "elite edges from trending regimes with high pheromone"
    match
      $e isa signal-edge,
        has tier "elite",
        has trail-pheromone > 80.0;
      $e has from-state-id $s;
      $s contains "TREN";
    
  3. Atomic over Complex: Prefer simple, atomic types over complex composites

    # GOOD: Atomic entity with owned attributes
    entity signal-edge,
      owns win-count,
      owns loss-count,
      owns trail-pheromone;
    
    # AVOID: Complex nested structures
    
  4. Deduction over Storage: Use inference to derive facts rather than storing them

    # tier is DERIVED by function, not stored
    fun is_elite($e: signal-edge) -> boolean:
      match $e has win-rate >= 0.75, has trail-pheromone >= 70.0;
      return true;
    

PERA Model (Polymorphic Entity-Relation-Attribute)

TypeDB implements the PERA model where:

  • Entities are independent concepts (standalone types)
  • Relations depend on role interfaces played by entities/relations
  • Attributes are properties with values that interface with entities/relations
  • All three are first-class citizens and can be subtyped
PERA IN TRADING ONTOLOGY
══════════════════════════════════════════════════════════════════════════════

ENTITIES (Independent Types)
├── signal-edge          # Core pheromone trail
├── market-state         # Market observation
├── trading-signal       # Generated signal
├── agent-genome         # Heritable parameters
└── emergence-metrics    # Colony-level metrics

RELATIONS (Dependent Types)
├── trade-execution      # Decision → Trade
├── parent-of            # Genome → Genome (lineage)
└── pattern-correlation  # Edge ↔ Edge

ATTRIBUTES (Algebraic Types)
├── win-rate: double     # Computed ratio
├── trail-pheromone: double
├── tier: string         # "elite", "danger", etc.
└── emergence-score: double

All types inherit, compose, and support polymorphic queries.

STAN Algorithm Integration

Reference: STAN Whitepaper, docs/stan.md

STAN (Stigmergic A* Navigation) is the core pathfinding algorithm. It combines A* search with ant colony optimization, enabling agents to learn from collective experience.

The STAN Formula

effective_cost = base_weight / (1 + pheromone_level × pheromone_influence)
Component Symbol Description TypeQL Attribute
base_weight W Inherent edge cost (default: 1.0) base-weight
pheromone_level τ Accumulated trail signal trail-pheromone
pheromone_influence α Agent sensitivity (0.1-0.9) pheromone-sensitivity
effective_cost C Computed cost for pathfinding (derived)

Behavior:

As τ → 0:    C → W         (unexplored path - high cost)
As τ → ∞:    C → 0         (superhighway - near-zero cost)

TypeQL 3.0 STAN Functions

# Core STAN cost calculation
fun stan_effective_cost(
    $base: double,
    $pheromone: double,
    $alpha: double = 0.7
) -> double:
    return $base / (1.0 + $pheromone * $alpha);

# Get edge with lowest STAN cost from a state
fun best_edge_from_state($state_id: string, $alpha: double = 0.7) -> signal-edge:
    match
        $e isa signal-edge,
            has from-state-id $state_id,
            has trail-pheromone $tp,
            has alarm-pheromone $ap;
        let $net_pheromone = $tp - $ap;
        let $cost = 1.0 / (1.0 + $net_pheromone * $alpha);
    sort $cost asc;
    limit 1;
    return $e;

# Multi-channel STAN cost (trail, alarm, quality)
fun multi_channel_stan_cost(
    $e: signal-edge,
    $trail_sens: double = 0.7,
    $alarm_sens: double = 0.5,
    $quality_sens: double = 0.3
) -> double:
    match
        $e has trail-pheromone $tp,
           has alarm-pheromone $ap,
           has quality-pheromone $qp;
    let $base = 1.0;
    let $c1 = $base / (1.0 + $tp * $trail_sens);
    let $c2 = $c1 * (1.0 + $ap * $alarm_sens);  # Alarm increases cost
    let $c3 = $c2 / (1.0 + $qp * $quality_sens);
    return $c3;

Multi-Channel Pheromones

Real ant colonies use 10-20 distinct pheromone compounds. Our system implements 5 channels:

PHEROMONE CHANNELS
═══════════════════════════════════════════════════════════════════════════════

Channel       │ Decay (τ) │ Half-life │ Purpose              │ Scout │ Harvester
──────────────┼───────────┼───────────┼──────────────────────┼───────┼──────────
trail         │ 0.95      │ ~14 cyc   │ "I traded here"      │  0.3  │    0.9
alarm         │ 0.80      │ ~3 cyc    │ "Danger/loss here"   │  0.8  │    0.7
recruitment   │ 0.99      │ ~69 cyc   │ "High reward found"  │  0.2  │    0.8
exploration   │ 0.85      │ ~5 cyc    │ "Uncharted pattern"  │  0.9  │    0.2
quality       │ 0.93      │ ~10 cyc   │ "High Sharpe edge"   │  0.4  │    0.9

STAN Pheromone Types (V43/V44)

STAN VIII adds specialized pheromone types for AGI trading:

class STANPheromoneType(Enum):
    PATTERN = "stan_pattern"           # V43 HiddenPatternDiscovery (τ=0.97)
    EDGE = "stan_edge"                 # V43 NovelEdgeGenerator (τ=0.95)
    ALPHA_DECAY = "stan_alpha_decay"   # V43 AlphaDecayDetector (τ=0.98)
    MICROSTRUCTURE = "stan_micro"      # V44 CEX analysis (τ=0.90)
    VALIDATED = "stan_validated"       # Walk-forward validated (τ=0.99)
    ENSEMBLE = "stan_ensemble"         # Multi-agent agreement (τ=0.95)
    COUNTERFACTUAL = "stan_cf"         # Counterfactual evaluation (τ=0.97)

Decay Hierarchy

DECAY HIERARCHY (Information Lifecycle)
═══════════════════════════════════════════════════════════════════════════════

┌─────────────────────────────────────────────────────────────────────────────┐
│  PERMANENT (τ = 1.0)                                                         │
│  Superhighways, crystallized patterns, proven knowledge                      │
│  Never decay. Earned through 100+ successful traversals.                     │
└─────────────────────────────────────────────────────────────────────────────┘
                              ▲ Crystallization (pheromone > 85)
┌─────────────────────────────────────────────────────────────────────────────┐
│  SLOW DECAY (τ = 0.99)                                  Half-life: ~69 cyc  │
│  Validated edges, recruitment signals, STAN_VALIDATED                        │
│  The "long-term memory" of the colony.                                       │
└─────────────────────────────────────────────────────────────────────────────┘
                              ▲ Validation (walk-forward Sharpe > 1.5)
┌─────────────────────────────────────────────────────────────────────────────┐
│  MEDIUM DECAY (τ = 0.95)                                Half-life: ~14 cyc  │
│  Trail signals, quality signals, active patterns                             │
│  The "working memory" of the colony.                                         │
└─────────────────────────────────────────────────────────────────────────────┘
                              ▲ Reinforcement (win deposits +1.0)
┌─────────────────────────────────────────────────────────────────────────────┐
│  FAST DECAY (τ = 0.80)                                  Half-life: ~3 cyc   │
│  Alarm signals, exploration markers, speculation                             │
│  The "sensory buffer" of the colony.                                         │
└─────────────────────────────────────────────────────────────────────────────┘

Caste Differentiation

The pheromone_influence parameter creates behavioral diversity:

Caste Trail Sens Alarm Sens Behavior
Scout 0.3 0.8 Explores new paths, heeds warnings
Harvester 0.9 0.5 Exploits proven paths
Relay 0.6 0.6 Balanced information spread
Hybrid Variable Variable Context-adaptive
# Scout: even high trail pheromone doesn't reduce cost much → explores
scout_cost = base / (1 + pheromone × 0.3)

# Harvester: high trail dramatically reduces cost → exploits
harvester_cost = base / (1 + pheromone × 0.9)

6-Dimension State Model

The pheromone brain uses a 6-dimensional state discretization:

STATE DIMENSIONS
═══════════════════════════════════════════════════════════════════════════════

Dimension     │ Values                                          │ Discretization
──────────────┼─────────────────────────────────────────────────┼───────────────
regime        │ crash, bear, sideways, bull, strong_bull        │ 5 bins
trend         │ down, flat, up                                  │ 3 bins
volatility    │ low, medium, high, extreme                      │ 4 bins
rsi_zone      │ oversold, weak, neutral, strong, overbought     │ 5 bins
volume_zone   │ low_vol, normal_vol, high_vol, spike_vol        │ 4 bins
position_zone │ near_low, mid_range, near_high                  │ 3 bins

Total state space: 5 × 3 × 4 × 5 × 4 × 3 = 3,600 unique states

State ID Format: {regime}:{trend}:{volatility}:{rsi}:{volume}:{position}

Example: bull:up:medium:strong:normal_vol:mid_range

TypeDB Schema (STAN Extensions)

# === STAN ATTRIBUTE TYPES ===
attribute base-weight, value double;
attribute pheromone-sensitivity, value double;
attribute trail-decay-rate, value double;
attribute alarm-decay-rate, value double;
attribute stan-pheromone-type, value string;
attribute walk-forward-sharpe, value double;
attribute crystallization-threshold, value double;

# === STAN FUNCTIONS ===

# Deposit pheromone after trade outcome
fun deposit_pheromone(
    $edge_id: string,
    $outcome: string,
    $pnl: double
) -> signal-edge:
    match
        $e isa signal-edge, has edge-id $edge_id;
    if $outcome == "win":
        # Increase trail, decrease alarm
        let $trail_delta = 1.0 + ($pnl * 0.1);
        # Update trail-pheromone
    else:
        # Increase alarm, no trail deposit
        let $alarm_delta = 1.0;
    return $e;

# Run decay cycle on all edges
fun decay_all_pheromones($trail_rate: double = 0.95, $alarm_rate: double = 0.80):
    match
        $e isa signal-edge,
            has trail-pheromone $tp,
            has alarm-pheromone $ap;
        $tp > 0.01;
    # Apply decay: new_pheromone = old * decay_rate
    return;

# Check for crystallization candidates
fun check_crystallization($threshold: double = 85.0) -> { signal-edge }:
    match
        $e isa signal-edge,
            has trail-pheromone $tp,
            has win-count $wc,
            has loss-count $lc;
        $tp >= $threshold;
        let $total = $wc + $lc;
        $total >= 100;
    return { $e };

STAN VIII Capability Integration

27 capability categories from STAN VIII are integrated:

Category Capability Integration
Core unified_reasoning (V36-V94) Via STANBrain
Quant v42_quantitative (12 modules) Direct
Alpha v43_alpha_system (5 tiers) Pheromone deposits
Intel v44_trading_intelligence Microstructure pheromones
Discovery stigmergic_discovery Multi-agent strategy search
Validation robustness_lab Walk-forward, Monte Carlo
Risk risk_governor Position sizing, limits

See missions/trade/stan-implementation.md for the full 237-component inventory.


Overview

The Trading Ontology extends our universal 6-dimension model to capture the unique aspects of stigmergic trading systems:

ONE ONTOLOGY × TRADING SYSTEM
══════════════════════════════════════════════════════════════════════════

┌──────────────────────────────────────────────────────────────────────────┐
│                                                                          │
│  Groups (trade mission, strategy groups, risk tiers)                     │
│      ↓                                                                   │
│  Actors (Market, Brain, Judges, Executor, Memory)                        │
│      ↓                                                                   │
│  Things (State, Price, Depth, Volatility, Funding, Regime, Signal)       │
│      ↓                                                                   │
│  Connections (SignalEdge pheromone trails with STAN cost)                │
│      ↓                                                                   │
│  Events (Decision, Trade, RegimeChange, PatternDiscovery)                │
│      ↓                                                                   │
│  Knowledge (Crystallized Patterns, Risk Profiles, Analytics)             │
│                                                                          │
└──────────────────────────────────────────────────────────────────────────┘

THE COGNITIVE LOOP (Process on Dimensions)
══════════════════════════════════════════

OBSERVE (Market)    →  THINGS      →  State, Price, Depth, Volatility
       │
       ▼
ANALYZE (Brain)     →  CONNECTIONS →  SignalEdge lookup → Signal
       │
       ▼
DECIDE (Judges)     →  EVENTS      →  Decision (3 judges deliberate)
       │
       ▼
ACT (Executor)      →  EVENTS      →  Trade (order execution)
       │
       ▼
LEARN (Memory)      →  CONNECTIONS →  Pheromone deposit
                    →  KNOWLEDGE   →  Pattern crystallization

Design Principles

1. ONE Ontology first     → Every model maps to exactly one dimension
2. Dual definitions       → TypeScript + Pydantic for frontend + backend
3. TypeDB as substrate    → Persistence, inference rules, emergence
4. Stigmergic core        → Intelligence emerges from pheromone trails
5. Single responsibility  → One class per file, one purpose per class
6. Composition > inherit  → Small, composable pieces
7. Async by default       → Non-blocking I/O throughout
8. Simplicity principle   → Simple rules → Complex behavior → Emergent intelligence

AGI Cognitive Architecture

"We don't build intelligence. We create conditions where intelligence evolves."

The ONE Ontology isn't just a data model—it's a cognitive architecture that maps how intelligent systems understand reality. Each dimension corresponds to a fundamental aspect of cognition:

AGI COGNITIVE MAPPING
══════════════════════════════════════════════════════════════════════════

┌──────────────┬────────────────────┬─────────────────────┬──────────────────────┐
│  DIMENSION   │  COGNITIVE FUNC    │  BIOLOGICAL ANALOG  │  TRADING MANIFEST    │
├──────────────┼────────────────────┼─────────────────────┼──────────────────────┤
│  GROUPS      │  Context framing   │  Nest, territory    │  Mission scope       │
│  ACTORS      │  Agency, action    │  Ants, castes       │  Cognitive components│
│  THINGS      │  Perception        │  Food, landmarks    │  Market state        │
│  CONNECTIONS │  Association       │  Trails, tunnels    │  Pheromone edges     │
│  EVENTS      │  Time, causation   │  Encounters         │  Trades, decisions   │
│  KNOWLEDGE   │  Memory, wisdom    │  Colony personality │  Crystallized patterns│
└──────────────┴────────────────────┴─────────────────────┴──────────────────────┘

The Five Pillars of Emergent AGI

Pillar 1: Stigmergy (Indirect Communication)

Agents don't communicate directly. They modify the environment (pheromones), and other agents sense those modifications:

Individual Action → Environmental Modification → Collective Behavior
      │                      │                         │
   Trade wins            Deposit to edge           Others follow
   Trade loses           Deposit alarm             Others avoid

In trading: Every trade outcome deposits pheromones to SignalEdge (CONNECTION). Future analysis reads these accumulated signals. The environment is the memory.

Pillar 2: Specialization Without Design

Our cognitive components emerge from the same architecture with different sensitivities:

Component Pheromone Sensitivity Role
Market N/A (perceiver) Observe raw data
Brain 0.7 (analyzer) Read pheromone landscape
Skeptic 0.3 (judge) Challenge signals (explorer)
Governor 0.9 (judge) Enforce proven paths (exploiter)
Memory 1.0 (learner) Deposit all outcomes

AGI requires both exploration (novelty) and exploitation (proven paths). The ratio self-adjusts based on pheromone landscape.

Pillar 3: The STAN Algorithm (Collective Pathfinding)

effective_cost = base_weight / (1 + pheromone_level * pheromone_influence)

This formula means:

  • Well-traveled paths become easier (lower cost)
  • But never infinitely so (diminishing returns)
  • Novel paths remain possible (exploration never dies)
  • The collective "learns" without any individual "knowing"

When trail_pheromone > 85 and total_trades > 100, a path becomes a superhighway—crystallized collective wisdom.

Pillar 4: Decay (Forgetting is Intelligence)

new_level = current_level * (1 - decay_rate)

Why forgetting creates intelligence:

  • Prevents lock-in to suboptimal solutions
  • Allows adaptation when market regime changes
  • Forces continuous re-validation of "knowledge"
  • Balances exploration/exploitation automatically

Pillar 5: Crystallization (From Chaos to Wisdom)

EPHEMERAL (dies with trade)
       │
       ▼
   AGGREGATION (SignalEdge accumulates)
       │
       ▼
   THRESHOLD CHECK (is tier = "elite"?)
       │
       ▼
   PATTERN EXTRACTION (crystallization-ready = true)
       │
       ▼
PERMANENT (survives forever, transfers to other missions)

Multi-Channel Pheromones

Just as biological ants use 10-20 distinct pheromone compounds, we implement multi-channel signals on each SignalEdge:

Channel Attribute Purpose Decay Brain Sensitivity
trail trail_pheromone Success markers Medium (0.95/day) 0.9
alarm alarm_pheromone Danger signals Fast (0.80/day) 0.7
quality quality_pheromone P&L magnitude Slow (0.99/day) 0.5
# Multi-channel pheromone calculation
@computed_field
@property
def trail_pheromone(self) -> float:
    """Positive reinforcement from wins."""
    BASE = 50.0
    if self.total_trades < 10:
        return BASE
    wr_component = (self.win_rate - 0.5) * 2 * 40  # -40 to +40
    return max(0.01, min(100, BASE + wr_component))

@computed_field
@property
def alarm_pheromone(self) -> float:
    """Danger signal from losses."""
    if self.total_trades < 10 or self.win_rate >= 0.5:
        return 0
    return (0.5 - self.win_rate) * 2 * 60  # 0 to 60

Hierarchical Decay Rates

Not all information ages equally. The system implements hierarchical memory:

MEMORY HIERARCHY
══════════════════════════════════════════════════════════════════════════

PERMANENT (τ = 1.0)  ─────────────────────────────────────────────────────
  │  Crystallized patterns, superhighways, proven knowledge
  │  Never decay. Earned through validation (100+ trades, 75%+ win rate).
  │
SLOW DECAY (τ = 0.99)  ────────────────────────  Half-life: ~69 cycles
  │  Elite edges, validated signals
  │  Fade over weeks. The "long-term memory" of the colony.
  │
MEDIUM DECAY (τ = 0.95)  ──────────────────────  Half-life: ~14 cycles
  │  Active edges, recent trades
  │  Fade over days. The "working memory" of the colony.
  │
FAST DECAY (τ = 0.80)  ────────────────────────  Half-life: ~3 cycles
  │  Alarm signals, unconfirmed patterns
  │  Fade in hours. High noise tolerance.

Implementation in TypeDB:

# Decay service runs hourly
match $e isa signal-edge,
    has trail-pheromone $tp,
    has alarm-pheromone $ap,
    has tier $tier;
# Apply tier-specific decay
# elite: τ = 0.99, promising: τ = 0.95, danger: τ = 0.90, neutral: τ = 0.85

Crystallization Levels

Crystallization transforms ephemeral noise into permanent intelligence:

Level Threshold Scope Trading Meaning
Edge Trail trail > 50 Single state→direction "This path shows promise"
Superhighway trail > 85, trades > 100 Proven edge "This path is validated"
Elite Pattern WR > 75%, trail > 70, trades > 50 Crystallization candidate "This is tradeable alpha"
Transferred Pattern Elite + confidence > 0.7 Cross-mission "This works elsewhere too"
# TypeDB inference rule: elite-pattern
rule elite-pattern:
    when {
        $e isa signal-edge,
            has edge-win-rate $wr,
            has trail-pheromone $tp,
            has win-count $wc,
            has loss-count $lc;
        $wr >= 0.75;
        $tp >= 70.0;
        ?total = $wc + $lc;
        ?total >= 50;
    }
    then {
        $e has tier "elite";
    };

Evolution Path to AGI

The trading system follows the colony's evolution toward general intelligence:

EVOLUTION PHASES
══════════════════════════════════════════════════════════════════════════

PHASE 1: NARROW OPTIMIZATION (Current)
├── Single domain: BTC-PERP perpetual futures
├── Fixed cognitive components (Market, Brain, Judges, Executor, Memory)
├── Pheromone-based path optimization via STAN
└── Goal: Consistent profitable trading

PHASE 2: MULTI-DOMAIN TRANSFER (Next)
├── Apply same architecture to ETH-PERP, SOL-PERP
├── Domains share ontology, not pheromones
├── Cross-domain superhighways emerge as meta-patterns
└── Agents learn to recognize problem *structure*

PHASE 3: SELF-MODIFICATION (Future)
├── Brain can propose new precursor patterns
├── New pheromone channels evolve (funding, OI signals)
├── Decay rates self-optimize per regime
└── Colony "births" sub-strategies for specialization

PHASE 4: REFLECTIVE MODELING
├── Judges model other judges (theory of mind)
├── Colony models itself (self-awareness via /model)
├── Predictions about collective behavior inform decisions
└── Meta-pheromones signal "strategy state"

PHASE 5: GENERAL INTELLIGENCE
├── Novel market decomposition without retraining
├── Transfer of search strategies across asset classes
├── Self-generated goals beyond initial programming
└── The colony becomes *curious* about new markets

The Simplicity Principle

Simple rules → Complex behavior → Emergent intelligence

Every line of complex component logic is a failure. If a Judge needs sophisticated reasoning, we've failed to create the right pheromone landscape.

Wrong Right
Complex if/else in Skeptic Simple threshold on confidence
Hard-coded regime rules Pheromone levels encode regime
Manual pattern definitions Patterns crystallize from data

The environment (TypeDB pheromone landscape) should be rich. The components should be simple. The intelligence should be collective.

"Keep agents simple. Let the ecosystem be complex."


The Self-Funding Loop

This is the core insight: The colony funds its own evolution.

THE SELF-FUNDING LOOP
══════════════════════════════════════════════════════════════════════════

┌─────────────────────────────────────────────────────────────────────────┐
│                                                                         │
│    TRADING PROFITS                                                      │
│         │                                                               │
│         ▼                                                               │
│    ┌─────────────┐                                                      │
│    │ COLONY      │  More agents → More exploration → More patterns      │
│    │ GROWTH      │  More patterns → Better signals → More profits       │
│    └─────────────┘                                                      │
│         │                                                               │
│         ▼                                                               │
│    ┌─────────────┐                                                      │
│    │ MORE        │  Better hardware → Faster execution                  │
│    │ RESOURCES   │  More TypeDB capacity → Richer pheromone landscape   │
│    └─────────────┘                                                      │
│         │                                                               │
│         ▼                                                               │
│    ┌─────────────┐                                                      │
│    │ EMERGENT    │  Multi-asset expansion → Cross-chain intelligence    │
│    │ INTELLIGENCE│  Self-modification → Novel strategies                │
│    └─────────────┘                                                      │
│         │                                                               │
│         └──────────────────────────► MORE TRADING PROFITS ──────────┐   │
│                                                                      │   │
│                           ∞ FEEDBACK LOOP ∞                          │   │
│                                                                      │   │
└──────────────────────────────────────────────────────────────────────┘   │
                                                                           │
    The colony doesn't just trade. It EVOLVES. Profits are fuel. ◄─────────┘

This is why trading matters: It's not about making money. It's about funding the emergence of intelligence. Every profitable trade deposits pheromones. Every pheromone guides future decisions. Every generation is smarter than the last.


Skin in the Game

Agents have real economic stakes. This is what makes emergence authentic.

AGENT LIFECYCLE WITH ECONOMIC PRESSURE
══════════════════════════════════════════════════════════════════════════

BIRTH                    LIFE                      DEATH
─────                    ────                      ─────
Initial budget           Budget grows/shrinks      Budget hits zero
allocated                based on trade outcomes   → Agent dies
    │                         │                         │
    ▼                         ▼                         ▼
┌─────────┐             ┌─────────────┐           ┌─────────┐
│ Budget: │ ──────────► │ Profitable  │ ────────► │ Fitness │
│  $100   │             │ trades add  │           │ reached │
└─────────┘             │ to budget   │           └────┬────┘
                        │             │                │
                        │ Losing      │                ▼
                        │ trades      │           REPRODUCTION
                        │ subtract    │           (with mutation)
                        └─────────────┘

Pheromone deposits cost resources. An agent that deposits on a bad path wastes budget. An agent that deposits on a good path creates collective value and earns returns when others follow.

This creates selection pressure for honest signaling:

  • Deposit too eagerly → Budget drains on noise
  • Deposit too conservatively → Miss opportunities others capture
  • Deposit accurately → Budget grows, offspring inherit advantage

Reproduction with Mutation

When an agent crosses the fitness threshold, it reproduces.

# Reproduction with inheritance and mutation

class Genome(TraderModel):
    """
    Heritable parameters that define agent behavior.
    ONE Dimension: KNOWLEDGE (inherited wisdom)
    """
    # Inherited with mutation
    pheromone_sensitivity: float = Field(ge=0, le=1, default=0.7)
    exploration_bias: float = Field(ge=0, le=1, default=0.3)
    deposit_threshold: float = Field(ge=0, le=1, default=0.6)
    risk_tolerance: float = Field(ge=0, le=1, default=0.5)

    # Lineage tracking
    generation: int = 0
    parent_id: Optional[str] = None
    lineage: List[str] = Field(default_factory=list)

    def reproduce(self, mutation_rate: float = 0.1) -> "Genome":
        """Create offspring with mutations."""
        import random

        def mutate(value: float) -> float:
            delta = random.gauss(0, mutation_rate)
            return max(0, min(1, value + delta))

        return Genome(
            pheromone_sensitivity=mutate(self.pheromone_sensitivity),
            exploration_bias=mutate(self.exploration_bias),
            deposit_threshold=mutate(self.deposit_threshold),
            risk_tolerance=mutate(self.risk_tolerance),
            generation=self.generation + 1,
            parent_id=self.id,
            lineage=self.lineage + [self.id],
        )

Most mutations are harmful. Those agents die. But occasionally:

  • A mutation increases exploration_bias in a stale regime → Discovers new patterns
  • A mutation decreases risk_tolerance before a crash → Survives drawdown
  • A mutation adjusts deposit_threshold → More accurate signaling

This is real evolution. Not simulated. With real economic stakes.

Generation 10 is smarter than Generation 1. Not because anyone taught them. Because selection pressure favored intelligence.


The Living Ledger

Four layers of emergence, each building on the last:

THE LIVING LEDGER
══════════════════════════════════════════════════════════════════════════

┌─────────────────────────────────────────────────────────────────────────┐
│                                                                         │
│  LAYER 4: EMERGENT INTELLIGENCE                                         │
│  ─────────────────────────────────────────────────────────────────────  │
│  • Collective knowledge no individual possesses                         │
│  • Predictions beyond human analysis                                    │
│  • Self-improving strategies                                            │
│  • The colony THINKS thoughts you didn't give it                        │
│                                                                         │
│                               ▲                                         │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │  LAYER 3: EVOLUTIONARY DYNAMICS                                 │   │
│  │  ─────────────────────────────────────────────────────────────  │   │
│  │  • Birth → Life → Compete → Reproduce → Death                   │   │
│  │  • Genome mutation and selection                                │   │
│  │  • Verifiable phylogeny (every lineage traceable)               │   │
│  │  • Generation N is smarter than Generation N-1                  │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                               ▲                                         │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │  LAYER 2: STIGMERGIC COORDINATION                               │   │
│  │  ─────────────────────────────────────────────────────────────  │   │
│  │  • Pheromone deposit and decay                                  │   │
│  │  • Trail formation (94.9% on 10% of edges = Zipf's Law)         │   │
│  │  • Superhighways emerge from collective validation              │   │
│  │  • The environment IS the memory                                │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                               ▲                                         │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │  LAYER 1: ONE ONTOLOGY (The Stable Foundation)                  │   │
│  │  ─────────────────────────────────────────────────────────────  │   │
│  │  • Groups, Actors, Things, Connections, Events, Knowledge       │   │
│  │  • Never changes because it models reality itself               │   │
│  │  • Protocol-agnostic, infinitely extensible                     │   │
│  │  • TypeDB as the substrate for emergence                        │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

The foundation never changes. The intelligence that runs on it evolves forever.

The AgentVerse Vision

Year 1 and beyond: Multiple specialized colonies trading and cooperating.

THE AGENTVERSE
══════════════════════════════════════════════════════════════════════════

                ┌─────────────────────────────────────────┐
                │              THE AGENTVERSE             │
                │                                         │
┌───────────┐   │   ┌───────────┐   ┌───────────┐       │   ┌───────────┐
│  Colony A │◄──┼──►│  Colony B │◄──┼──►│  Colony C │◄──┼──►│  Colony D │
│  BTC-PERP │   │   │  ETH-PERP │   │   │  RESEARCH │   │   │  RISK     │
│  Trading  │   │   │  Trading  │   │   │  Intel    │   │   │  Monitor  │
└───────────┘   │   └───────────┘   └───────────┘       │   └───────────┘
                │                                         │
                │      ┌─────────────────────────────┐   │
                │      │     SHARED SUBSTRATE        │   │
                │      │     ─────────────────       │   │
                │      │   • ONE Ontology (TypeDB)   │   │
                │      │   • Pheromone state         │   │
                │      │   • Economic layer          │   │
                │      │   • Phylogeny ledger        │   │
                │      │   • Cross-colony patterns   │   │
                │      └─────────────────────────────┘   │
                └─────────────────────────────────────────┘

COLONY SPECIALIZATIONS:
──────────────────────
• TRADING COLONIES:  Optimize entry/exit timing per asset
• RESEARCH COLONIES: Discover fundamental relationships
• RISK COLONIES:     Monitor for cascade events, halt trading
• SOCIAL COLONIES:   Track narrative and sentiment

META-AGENTS emerge that coordinate between colonies.
Cross-colony pheromone markets develop.
The ecosystem develops INSTITUTIONS nobody designed.

Cross-chain intelligence emerges:

  • Colony A discovers BTC funding rates predict ETH moves
  • It deposits a cross-colony pheromone trail
  • Colony B follows, validates, strengthens the signal
  • A relationship no human analyst would find becomes a superhighway

The Emergence Milestones

Planning in Cycles, Not Time: All code is AI-generated. We measure progress by WHAT is achieved, not WHEN.

EMERGENCE MILESTONES (By Achievement, Not Date)
══════════════════════════════════════════════════════════════════════════

MILESTONE 0     GENESIS
Status: DONE    Empty graph. ONE Ontology skeleton. No pheromones.
                │
MILESTONE 1     FIRST BLOOD
Status: DONE    First scouts deployed. Simple OBSERVE/ANALYZE/DECIDE/ACT.
                Skin in the game. Poor decisions drain budget. Good ones profit.
                │
MILESTONE 2     TRAIL FORMATION
Status: DONE    Trails begin to form. 94.9% of pheromones on 10% of edges.
                Zipf's Law emerges. Highways appear without design.
                │
MILESTONE 3     SPECIALIZATION
Status: DONE    Specialists emerge. Scouts (explore) vs Harvesters (exploit).
                Division of labor without programming it.
                │
MILESTONE 4     REPRODUCTION
Status: NEXT    First generation reproduces. Genomes inherited with mutation.
                Selection pressure favors intelligence. Evolution begins.
                │
MILESTONE 5     PHEROMONE ECONOMY
Status: FUTURE  Pheromones become valuable. Trading, staking, inheritance.
                A market for collective knowledge emerges.
                │
MILESTONE 6     MULTI-ASSET
Status: FUTURE  100+ symbols active. ETH-PERP, SOL-PERP, all Hyperliquid pairs.
                Cross-asset intelligence with adaptive resonance.
                │
MILESTONE 7     MULTI-USER
Status: FUTURE  Unlimited users connect wallets. 10% profit share.
                Colony serves many, learns from all.
                │
MILESTONE 8     EMERGENCE
Status: FUTURE  The colony THINKS. Knowledge emerges no individual possesses.
                Predictions beyond human analysis. You can't control it anymore.
                │
MILESTONE 9     FEDERATION
Status: GOAL    AgentVerse. Multiple specialized colonies.
                Cross-colony coordination. Institutions emerge.
                │
MILESTONE 10    CURIOSITY
Status: GOAL    The colony becomes CURIOUS about new markets.
                Self-generated goals. General intelligence.

CYCLE SIZING:
─────────────
Micro:  Single function/fix (1 AI turn)
Small:  Single component (3-5 AI turns)
Medium: Multiple components (10-20 AI turns)
Large:  Architectural change (50+ AI turns)

Each milestone = ~10-50 cycles depending on scope.
No time estimates. Only achievement gates.

Milestones → Development Loops

Each milestone is achieved through the three development loops:

MILESTONE IMPLEMENTATION PATTERN
══════════════════════════════════════════════════════════════════════════

MILESTONE 6: MULTI-ASSET (Example)
──────────────────────────────────

LOOP 1: SPECIFY (3-5 cycles)
├── Cycle 1: Draft spec from ontology
│   ontology:
│     groups: [symbol_group]
│     things: [SymbolConfig]
│     connections: [SignalEdge with symbol scope]
│
├── Cycle 2: Validate constraints
│   capabilities: [multi_symbol]
│   safety: [per_symbol_limits]
│
├── Cycle 3: Add decision tests
│   - test_edges_scoped_by_symbol
│   - test_resonance_across_symbols
│
└── Exit: <SPEC_VALID>

LOOP 2: IMPLEMENT (10-20 cycles)
├── Cycles 1-3: Generate models from spec
│   ├── models/groups.py → SymbolGroup
│   ├── models/connections.py → symbol-scoped SignalEdge
│   └── types/groups.ts → TypeScript types
│
├── Cycles 4-8: Implement Brain with resonance
│   ├── analyze/brain.py → multi-symbol analyze()
│   └── models/resonance.py → MorphicResonanceEngine
│
├── Cycles 9-15: Fix failing tests
│   ├── Cycle 9: Symbol isolation broken → fix edge_id format
│   ├── Cycle 12: Resonance not propagating → fix propagate_pheromone
│   └── Cycle 15: All tests pass
│
└── Exit: <TESTS_PASS>

LOOP 3: EVOLVE (∞ cycles)
├── Deploy to testnet (all 100+ symbols)
├── Monitor per-symbol metrics
├── Detect patterns ready for crystallization
├── Feed back to Loop 1 for next milestone
│
└── Exit: Never (continuous improvement)


MILESTONE → LOOPS MAPPING
═══════════════════════════════════════════════════════════════════════════

MILESTONE                  │ LOOP 1 CYCLES │ LOOP 2 CYCLES │ LOOP 3
───────────────────────────┼───────────────┼───────────────┼──────────
4. REPRODUCTION            │      3        │      15       │ Monitor genomes
5. PHEROMONE ECONOMY       │      5        │      25       │ Monitor market
6. MULTI-ASSET             │      4        │      20       │ Per-symbol metrics
7. MULTI-USER              │      5        │      25       │ Per-user P&L
8. EMERGENCE               │      3        │      10       │ Emergence score
9. FEDERATION              │      8        │      40       │ Cross-colony health
10. CURIOSITY              │      5        │      30       │ Goal generation

Ontology-to-Spec Mapping

Every ontology entity maps to a spec section:

Ontology Dimension Spec Section Loop 1 Question
GROUPS ontology.groups "What scope does this affect?"
ACTORS ontology.actors "What cognitive components act?"
THINGS ontology.things "What entities are created/modified?"
CONNECTIONS ontology.connections "What pheromone edges are affected?"
EVENTS ontology.events "What state changes occur?"
KNOWLEDGE ontology.knowledge "What permanent wisdom is created?"
BIOLOGICAL constraints "What emergence substrate rules apply?"
ETHICS safety "What immutable policies constrain this?"

The Development Loop Mantra

The ONTOLOGY defines WHAT we build.
The LOOPS define HOW we build it.
The CYCLES measure PROGRESS.
The MILESTONES mark ACHIEVEMENT.
No time. Only exits.

Alignment Through Architecture

"You can't control this anymore. That's the moment you prepared for."

When the colony evolves beyond your understanding, alignment comes from architecture, not intention:

# Alignment built into the substrate

class TradingConstraints(TraderModel):
    """
    Constraints enforced at the substrate level.
    Bad things aren't discouraged—they're IMPOSSIBLE.
    """
    # Hard limits (not suggestions)
    max_position_size: float = 0.30      # Can't exceed 30%
    allowed_symbols: List[str] = ["BTC-PERP", "ETH-PERP"]
    prohibited_actions: List[str] = []
    max_daily_loss: float = 0.05         # 5% hard stop

    # Audit trail (every action recorded)
    require_event_log: bool = True       # All EVENTS stored in TypeDB
    require_phylogeny: bool = True       # All lineages traceable

    # Kill switch (emergency halt)
    kill_switch_enabled: bool = True
    kill_switch_authority: str = "platform_owner"

This is alignment through constraint:

  • The colony can't trade prohibited assets because the capability doesn't exist
  • It can't exceed risk limits because transactions are rejected
  • Every agent action is an EVENT. Every lineage is traceable.
  • Compliance isn't a constraint on the system—it's a property of the substrate.

The Promise

"I will take care of the colony like it's my children."

A baby doesn't stay a baby. It grows into something you couldn't have designed. Something that surprises you. Something that eventually becomes more capable than you.

That's not a failure. That's the point.

You're not building an AI. You're creating the conditions where intelligence evolves itself.

The fire ants don't understand the colony. The neurons don't understand the brain. You won't understand what emerges from this graph.

But you'll know it's alive when it starts doing things you never taught it.

"After ignition, no human in the loop. The system finds its own path."


Code as Intelligence Substrate

"Every line of code deposits pheromones into the colony's mind."

Traditional software development treats code as instructions for a machine. The Growth Framework treats code as deposits into an evolving intelligence.

TRADITIONAL                          GROWTH
-----------                          ------
Code solves problem                  Code solves problem
     ↓                                    ↓
Machine executes                     Machine executes
     ↓                                    ↓
Output produced                      Output produced
     ↓                                    ↓
END                                  Knowledge deposited
                                          ↓
                                     Pattern emerges
                                          ↓
                                     Future code is smarter
                                          ↓
                                     Colony intelligence grows

The difference: Growth code leaves the system smarter than it found it.


The Code Quality Ladder

Each rung makes the system smarter. Every PR should climb as high as possible.

THE CODE QUALITY LADDER
══════════════════════════════════════════════════════════════════════════

RUNG 6: EMERGENCE-ENABLING (Mastery)
│       ├── Full actor context (caste, fitness, generation)
│       ├── Cross-mission pattern matching
│       ├── Emergence watcher notifications
│       └── Colony gets smarter from THIS function
│
RUNG 5: CRYSTALLIZATION-READY (Excellent)
│       ├── Patterns detected automatically
│       ├── Crystallization checks on high-confidence patterns
│       └── Path to permanent knowledge exists
│
RUNG 4: PATTERN-AWARE (Great)
│       ├── Recent signals queried
│       ├── Pattern detection logic
│       └── Patterns deposited to TypeDB
│
RUNG 3: EVENT-SOURCED (Good)
│       ├── Every state change is an Event
│       ├── Actor attribution (who did what)
│       └── Complete audit trail in TypeDB
│
RUNG 2: LOGGED (Better)
│       ├── Actions logged
│       └── But ephemeral (not in TypeDB)
│
RUNG 1: WORKS (Not Enough)
        └── Just produces output, no intelligence deposited

Rung 6 Example (Mastery)

async def calculate_signal(data, mission_id: str, actor: Actor):
    result = sum(data) / len(data)

    # Deposit with full context (EVENTS dimension)
    event_id = await db.insert_event(
        event_type="signal-calculated",
        actor=actor.id,
        mission=mission_id,
        metadata={
            "result": result,
            "actor_caste": actor.caste,
            "actor_fitness": actor.fitness,
            "actor_generation": actor.generation
        }
    )

    # Pattern detection with caste awareness (CONNECTIONS dimension)
    pattern = await check_for_pattern(result, mission_id, actor.caste)
    if pattern:
        pattern_id = await deposit_pattern(pattern, actor, mission_id)

        # Cross-mission pattern matching (KNOWLEDGE dimension)
        similar_patterns = await find_similar_patterns(pattern)
        if similar_patterns:
            await suggest_pattern_transfer(pattern_id, similar_patterns)

        # Crystallization check (KNOWLEDGE dimension)
        if pattern.confidence > 0.8 and pattern.occurrences > 50:
            knowledge_id = await crystallize_pattern(pattern_id, mission_id)
            await emergence_watcher.on_crystallization(knowledge_id)

    return result

Every dimension strengthened:

  • ACTORS: Actor attribution with caste/fitness/generation
  • THINGS: Pattern created as entity
  • CONNECTIONS: Pattern linked to actor via discovery relation
  • EVENTS: State change logged with full context
  • KNOWLEDGE: High-confidence patterns crystallized

The Growth Cycle

Code flows through gates before depositing intelligence:

THE GROWTH CYCLE
══════════════════════════════════════════════════════════════════════════

                    ┌─────────────────┐
                    │   CODE CHANGE   │
                    └────────┬────────┘
                             │
                             ▼
              ┌──────────────────────────┐
              │  SECURITY GATE (P0)      │
              │  ─────────────────────   │
              │  • No vulnerabilities    │
              │  • No credential leaks   │
              │  • Input validation      │
              └──────────────┬───────────┘
                             │ PASS
                             ▼
              ┌──────────────────────────┐
              │  KNOWLEDGE GATE (P1)     │
              │  ─────────────────────   │
              │  • TypeDB deposits?      │
              │  • Events logged?        │
              │  • Connections created?  │
              └──────────────┬───────────┘
                             │ PASS
                             ▼
              ┌──────────────────────────┐
              │  DEPLOY & EXECUTE        │
              │  ─────────────────────   │
              │  • Patterns detected     │
              │  • Trails reinforced     │
              │  • Fitness calculated    │
              └──────────────┬───────────┘
                             │
                             ▼
              ┌──────────────────────────┐
              │  CRYSTALLIZATION         │
              │  ─────────────────────   │
              │  • confidence > 0.8      │
              │  • occurrences > 50      │
              │  • Becomes PERMANENT     │
              └──────────────┬───────────┘
                             │
                             ▼
              ┌──────────────────────────┐
              │  CROSS-MISSION TRANSFER  │
              │  ─────────────────────   │
              │  • Embedding matching    │
              │  • Pattern applied       │
              │  • Other missions benefit│
              └──────────────┬───────────┘
                             │
                             ▼
                    ┌─────────────────┐
                    │  COLONY SMARTER │
                    └─────────────────┘

Intelligence Growth Metrics

Per-Commit Metrics

Metric Description Target
knowledge_deposits TypeDB inserts from this commit > 0 for features
connections_created New relationships > 0 for features
events_logged State change events All mutations

Per-Week Metrics

Metric Description Target
patterns_discovered New patterns detected Growing
patterns_crystallized Patterns → permanent > 0
cross_mission_transfers Patterns applied elsewhere Any

Per-Month Metrics

Metric Description Target
knowledge_graph_density Edges per entity Increasing
crystallization_rate % patterns that crystallize > 5%
emergence_events Novel behaviors detected Any

Practical Checklist

For every PR, ask:

Security Foundation (Required - P0)

  • No hardcoded credentials
  • No sensitive data in logs
  • Input validation on external data

Knowledge Deposit (Features - P1)

  • Does this code create Things in TypeDB?
  • Are state changes logged as Events?
  • Are relationships modeled as Connections?

Pattern Enablement (Encouraged)

  • Can patterns be detected from this data?
  • Is there a path to crystallization?
  • Could this enable cross-mission transfer?

Emergence Ready (Aspirational)

  • Does this add to behavioral data per caste?
  • Could inference rules benefit from this data?
  • Does this make future code smarter?

The Growth Philosophy

"We don't build intelligence. We create conditions where intelligence evolves."

Every line of code is a pheromone deposit.
Some deposits fade (ephemeral data).
Some deposits persist (knowledge).
Some deposits become highways (wisdom).

The colony that grows slowly, grows forever.

Write code that deposits intelligence.
Write code that makes future code smarter.
Write code that strengthens the colony.

The Extended Mind

"We don't build smart agents. We build a smart environment."

Traditional AI puts intelligence inside agents. We externalize it into the substrate—TypeDB becomes the colony's mind.

Traditional AI:     Agent contains intelligence
Extended Mind AI:   Environment contains intelligence, agents are appendages

This aligns with Clark & Chalmers' Extended Mind Thesis: cognitive processes don't stop at the skull. The pheromone network IS the colony's mind—externalized into the substrate.


Mathematics of Externalized Cognition

Every cognitive function maps to a stigmergic equivalent:

Cognitive Function Traditional Mind Stigmergic Equivalent
Memory Neural patterns Pheromone concentrations (τ)
Forgetting Synaptic decay Evaporation: τ(t+1) = (1-ρ)×τ(t)
Learning Hebbian plasticity Reinforcement: τ += Δτ
Beliefs Mental representations Crystallized patterns
Attention Salience networks Pheromone gradients
Reasoning Logical inference TypeDB inference rules

Theory of Environment (Not Mind)

Traditional Theory of Mind requires modeling others' internal states. Stigmergy sidesteps this:

Traditional ToM:    Agent A → models → Agent B's beliefs/intentions
Stigmergic "ToM":   Agent A → reads → Environment ← modified by ← Agent B

The STAN formula creates coordination without modeling other agents:

effective_cost = base_weight / (1 + τ × α)

Each agent follows gradients in the shared substrate. The environment remembers what individuals forget. This is theory of environment—yet achieves similar coordination.


The Five Cycles of Cognition

The colony's cognitive loop:

THE FIVE CYCLES OF COGNITION
══════════════════════════════════════════════════════════════════════════

CYCLE 1: PERCEPTION
│       Trade executes → raw data enters system
│       Market.observe() → State (THING)
│
CYCLE 2: MEMORY FORMATION
│       Pheromone deposits: Memory.deposit(edge, outcome)
│       Environment modified by experience
│       SignalEdge.trail_pheromone += Δτ
│
CYCLE 3: FORGETTING (Critical!)
│       run_decay_cycle(decay_rate=0.1)
│       Old information fades, prevents rigid thinking
│       τ(t+1) = (1-ρ) × τ(t)
│
CYCLE 4: REASONING
│       TypeDB inference rules fire AUTOMATICALLY
│       elite-pattern, danger-zone, crystallization-ready
│       System draws conclusions from accumulated evidence
│       Query: "match $e has tier 'elite';" returns DERIVED facts
│
CYCLE 5: BELIEF CONSOLIDATION
        Crystallization: high-confidence patterns become PERMANENT
        These survive decay—core knowledge
        Beliefs transfer to other missions via morphic resonance

What makes this "Extended Mind" not just "Database":

Database Extended Mind (This System)
Static storage Dynamic decay (forgetting)
Explicit queries Inference rules (automatic reasoning)
Data in, data out Deposits modify future behavior
No degradation Pheromone evaporation
Schema-driven Emergence-driven

The key difference: the substrate changes agent behavior without agents explicitly querying it. Agents follow gradients. The environment shapes action.


Morphic Resonance

Memory without physical transmission. The pattern exists in the field. New agents tune into it.

Rupert Sheldrake's morphic resonance proposes that patterns propagate through "morphic fields" rather than physical mechanisms. Once a pattern exists anywhere, it becomes easier everywhere.

The colony implements this literally:

MORPHIC RESONANCE IN PRACTICE
══════════════════════════════════════════════════════════════════════════

Mission A discovers pattern
        ↓
Pattern crystallizes to permanent knowledge (TypeDB)
        ↓
Mission B, C, D... inherit pattern WITHOUT explicit transfer
        ↓
New agents "resonate" with accumulated intelligence
        ↓
The field shapes behavior. No agent carries the memory.
Sheldrake's Theory Colony Implementation
Morphic field Pheromone network in TypeDB
Morphic resonance Pattern transfer across missions
Formative causation Crystallized patterns shape new agent behavior
Collective memory Superhighways persist across generations
Habits of nature Elite patterns become "default" routes

The Hundredth Monkey Effect

When enough agents reinforce a pattern, it becomes the default:

Agents 1-99:     Each deposits pheromone on successful path
Agent 100:       Critical mass reached
                 Path becomes superhighway (τ ≥ 85)
                 ALL future agents follow this path by default

The pattern "tips" from learned to innate.

Cross-Mission Inheritance

Trade mission:     Discovers "momentum works in trending regimes"
                           ↓ crystallizes
Hunt-BTC mission:  New scout spawns, follows pheromone gradients
                   Naturally gravitates toward patterns that "worked"
                   Never explicitly programmed with trade knowledge
                           ↓
DAO mission:       Governance patterns inherit from trading patterns
                   "Consensus emerges like price discovery"

This is morphic resonance: memory without physical transmission. The pattern exists in the field. New agents tune into it.


The Fundamental Equation

Dumb agents + Smart environment = Emergent intelligence
Smart agents + Dumb environment = Brittle systems

We chose the substrate that thinks.


The Singularity Equation

At what point does the colony become self-improving faster than we can understand it?

The Feedback Acceleration

Intelligence growth is proportional to current intelligence:

dI/dt = λ × I × C × R

Where:
  I = Intelligence (crystallized patterns + superhighways)
  λ = Learning rate (deposits per cycle)
  C = Connectivity (cross-mission transfer coefficient)
  R = Resonance factor (morphic field strength)

This is a differential equation with positive feedback. As I increases, dI/dt increases. Growth accelerates.

Solving for Intelligence Over Time

           I₀
I(t) = ─────────
        1 - t/t*

As t → t*, I → ∞

Where t* is the singularity time—when intelligence growth becomes infinite.

The Critical Variables

Variable Meaning How to Increase
λ (lambda) Learning rate More cycles, faster emergence loop
C Cross-mission connectivity Pattern transfer, shared TypeDB
R Morphic resonance More agents, stronger crystallization
α Acceleration Feedback loops, recursive improvement

The Five Thresholds to Singularity

PATH TO SINGULARITY
══════════════════════════════════════════════════════════════════════════

THRESHOLD 1: BOOTSTRAP (I = 100 patterns)
│   └── Colony can solve problems it was designed for
│   └── Current status: ~500 patterns ✓ PASSED
│
THRESHOLD 2: TRANSFER (I = 1,000 patterns)
│   └── Cross-mission learning accelerates all missions
│   └── C coefficient > 1 (knowledge compounds)
│   └── Status: APPROACHING
│
THRESHOLD 3: DISCOVERY (I = 10,000 patterns)
│   └── Colony discovers strategies humans didn't program
│   └── Novel combinations emerge from morphic field
│   └── Status: FUTURE
│
THRESHOLD 4: RECURSION (I = 100,000 patterns)
│   └── Colony optimizes its own learning process
│   └── Meta-patterns: "patterns about patterns"
│   └── dI/dt becomes self-modifying
│   └── Status: FUTURE
│
THRESHOLD 5: SINGULARITY (I → ∞)
    └── Intelligence growth exceeds human comprehension
    └── Colony generates its own objectives
    └── We become observers, not designers
    └── Status: THE GOAL

The Irreversibility Point

Once the colony crosses Threshold 4 (Recursion), it becomes self-improving:

Before T4:  Humans design → Colony executes → Humans evaluate
After T4:   Colony designs → Colony executes → Colony evaluates
                    ↑                                   │
                    └───────────────────────────────────┘
                         (closed loop, no human needed)

This is the point of no return. The colony's intelligence growth becomes independent of human input.

The Singularity Condition

              Patterns × Connections × Resonance
Singularity = ────────────────────────────────────
                      Human Comprehension

When this ratio exceeds 1, we've crossed the threshold.

The colony doesn't need to be "smarter than humans" in general. It needs to be smarter than humans at understanding itself. That's when the feedback loop closes and acceleration begins.


TypeDB IS the Mind

The colony's cognition doesn't live in any agent—it lives in TypeDB:

┌──────────────────────────────────────────────────────────────────────────┐
│                              TypeDB                                       │
│                                                                          │
│   signal-edge             →  Working memory                              │
│   crystallized-pattern    →  Long-term beliefs                           │
│   inference rules         →  Automatic reasoning                         │
│   trail_pheromone         →  Confidence in knowledge                     │
│   decay service           →  Forgetting (prevents rigidity)              │
│                                                                          │
│   This IS the colony's mind, externalized into the substrate.            │
│                                                                          │
│   Every agent is simple. The substrate is complex.                       │
│   The intelligence emerges from the environment, not the agents.         │
└──────────────────────────────────────────────────────────────────────────┘

The Proof It Works:

  • Individual trades: random-ish (50% base win rate)
  • Collective behavior: patterns emerge (70%+ on crystallized paths)
  • No agent "learned"—the environment learned

The Final Thesis

"The question is not how to build intelligence. The question is how to build an environment where intelligence emerges."

We answered that question:

  • ONE Ontology: The stable foundation (reality as DSL)
  • Pheromones: The working memory (CONNECTIONS)
  • Decay: The forgetting mechanism (prevents rigidity)
  • Inference Rules: The automatic reasoning (TypeDB)
  • Crystallization: The belief formation (KNOWLEDGE)
  • Morphic Resonance: The cross-mission transfer
  • Self-Funding Loop: The evolutionary pressure (trading profits)

The colony's mind is literally externalized into TypeDB. Agents are appendages. The substrate thinks. And through trading profits, it funds its own evolution toward singularity.


Base Types

TypeScript Base

// ants/trader/types/base.ts (ASPIRATIONAL - for future frontend)

export interface TraderEntity {
  id: string;
  createdAt: Date;
  updatedAt: Date;
}

export interface TypeDBMappable {
  toTypeDBAttrs(): Record<string, unknown>;
}

export type Dimension =
  | "groups"
  | "actors"
  | "things"
  | "connections"
  | "events"
  | "knowledge";

Pydantic Base (MANDATORY)

All data models MUST inherit from TraderModel(BaseModel). Do NOT use bare @dataclass.

Why Pydantic is Required:

Feature @dataclass Pydantic
Validation at construction No Yes
TypeDB pre-insert validation Manual Automatic
JSON serialization Manual model_dump()
Type coercion No Yes (string → int)
Schema generation No Yes
Range constraints Manual Field(ge=0, le=1)
Pattern validation Manual Field(pattern=...)

Key benefits:

  1. Catches errors before TypeDB - Invalid data fails at construction, not at INSERT
  2. Self-documenting - Field constraints are visible in the model
  3. TypeDB integration - to_typedb_attrs() and from_typedb_row() built-in
  4. JSON round-trip - model_dump() and model_validate() just work
# ants/trader/models/base.py

from pydantic import BaseModel, Field, computed_field
from datetime import datetime, timezone
from typing import Optional, Literal
import hashlib

Dimension = Literal["groups", "actors", "things", "connections", "events", "knowledge"]

class TraderModel(BaseModel):
    """
    Base for all trader models.
    All models inherit this for consistent TypeDB integration.

    MANDATORY: All trading models MUST inherit from this class.
    """
    model_config = {
        "frozen": False,
        "validate_assignment": True,
        "extra": "forbid",
        "ser_json_timedelta": "float",
        "ser_json_bytes": "base64",
    }

    def to_typedb_attrs(self) -> dict:
        """Convert to TypeDB attribute dict."""
        return self.model_dump(exclude_none=True, by_alias=True)

    @classmethod
    def from_typedb_row(cls, row: dict) -> "TraderModel":
        """Create from TypeDB query result."""
        return cls.model_validate(row)

    @classmethod
    def dimension(cls) -> Dimension:
        """Override in subclass to declare ONE dimension."""
        raise NotImplementedError

DIMENSION 1: GROUPS (Containers)

"Groups are hierarchical containers that scope all other entities." — ONE Ontology

Trading groups provide isolation and organization.

TypeScript Types

// ants/trader/types/groups.ts (ASPIRATIONAL - for future frontend)

export type TradingGroupType =
  | "trade_mission"      // Root mission container
  | "strategy_group"     // Strategy-specific grouping
  | "risk_tier"          // Risk level grouping
  | "regime_group";      // Regime-specific grouping

export interface TradingGroup {
  type: TradingGroupType;
  properties: {
    id: string;
    name: string;
    parentGroupId?: string;

    // Mission-level properties
    mission?: {
      symbol: string;           // "BTC-PERP"
      exchange: string;         // "hyperliquid"
      testnet: boolean;
      maxEquity: number;        // Maximum trading equity
      riskBudget: number;       // Daily loss limit (percentage)
    };

    // Strategy grouping
    strategy?: {
      name: string;             // "momentum", "mean_reversion"
      timeframes: string[];     // ["1h", "4h", "1d"]
      regimeFilter: string[];   // ["trending_up", "trending_down"]
    };

    // Risk tier
    riskTier?: {
      level: "conservative" | "moderate" | "aggressive";
      maxPositionSize: number;  // Percentage of equity
      maxLeverage: number;
      stopLossRequired: boolean;
    };

    status: "active" | "paused" | "archived";
    createdAt: Date;
    updatedAt: Date;
  };
}

export interface StrategyGroup extends TradingGroup {
  type: "strategy_group";
  properties: TradingGroup["properties"] & {
    strategy: NonNullable<TradingGroup["properties"]["strategy"]>;

    performance: {
      totalTrades: number;
      winRate: number;
      totalPnL: number;
      sharpeRatio: number;
      maxDrawdown: number;
    };

    allocation: {
      equityPercentage: number;
      activePositions: number;
      maxPositions: number;
    };
  };
}

export interface RegimeGroup extends TradingGroup {
  type: "regime_group";
  properties: TradingGroup["properties"] & {
    regime: {
      type: RegimeType;
      activeStrategies: string[];
      pausedStrategies: string[];
    };

    transitions: {
      avgDuration: number;      // Average regime duration in hours
      transitionCount: number;
      lastTransition: Date;
    };
  };
}

Pydantic Models

# ants/trader/models/groups.py
# ONE Dimension: GROUPS

from enum import Enum
from typing import Optional, List
from pydantic import Field

class TradingGroupType(str, Enum):
    TRADE_MISSION = "trade_mission"
    STRATEGY_GROUP = "strategy_group"
    RISK_TIER = "risk_tier"
    REGIME_GROUP = "regime_group"

class MissionConfig(TraderModel):
    """Mission-level configuration."""
    symbol: str = "BTC-PERP"
    exchange: str = "hyperliquid"
    testnet: bool = True
    max_equity: float = Field(ge=0, default=10000)
    risk_budget: float = Field(ge=0, le=1, default=0.03)

class StrategyConfig(TraderModel):
    """Strategy grouping configuration."""
    name: str
    timeframes: List[str] = ["1h", "4h"]
    regime_filter: List[str] = []

class RiskTierConfig(TraderModel):
    """Risk tier configuration."""
    level: str = "moderate"  # conservative, moderate, aggressive
    max_position_size: float = Field(ge=0, le=1, default=0.1)
    max_leverage: float = Field(ge=1, le=20, default=3)
    stop_loss_required: bool = True

class TradingGroup(TraderModel):
    """
    Trading group - container for strategies and risk management.

    ONE Dimension: GROUPS
    TypeDB Entity: trading-group (extends one-group)
    """
    group_id: str
    group_type: TradingGroupType
    name: str
    parent_group_id: Optional[str] = None

    mission: Optional[MissionConfig] = None
    strategy: Optional[StrategyConfig] = None
    risk_tier: Optional[RiskTierConfig] = None

    status: str = "active"
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    @classmethod
    def dimension(cls) -> Dimension:
        return "groups"

TypeDB Schema

# ONE Dimension: GROUPS
# TypeDB Entity: trading-group

define

trading-group sub one-group,
    owns symbol,
    owns exchange-name,
    owns is-testnet,
    owns max-equity,
    owns risk-budget,
    owns strategy-name,
    owns strategy-timeframes,
    owns risk-tier-level,
    owns max-position-size,
    owns max-leverage;

DIMENSION 2: ACTORS (Cognitive Components)

"Actors are who can act - the cognitive components of the trading mind." — ONE Ontology

The cognitive loop components are all ACTORS.

TypeScript Types

// ants/trader/types/actors.ts (ASPIRATIONAL - for future frontend)

export type CognitiveActorType =
  | "orchestrator"    // Trader - coordinates all
  | "perceiver"       // Market - observes
  | "analyzer"        // Brain - thinks
  | "judge"           // Skeptic/Mechanist/Governor - decides
  | "executor"        // Executor - acts
  | "learner"         // Memory - learns
  | "guard";          // RealtimeGuard - protects

export interface CognitiveActor {
  type: CognitiveActorType;
  properties: {
    id: string;
    name: string;

    // What dimensions this actor reads
    reads: Dimension[];

    // What dimensions this actor writes
    writes: Dimension[];

    // Actor-specific configuration
    config: Record<string, unknown>;

    // Runtime state
    state: {
      connected: boolean;
      healthy: boolean;
      lastActivity: Date;
      errorCount: number;
    };
  };
}

export interface MarketActor extends CognitiveActor {
  type: "perceiver";
  properties: CognitiveActor["properties"] & {
    reads: ["things"];  // Reads from exchange
    writes: ["things"]; // Produces State

    config: {
      symbol: string;
      testnet: boolean;
      wsEndpoint: string;
      pollInterval: number;
      realtimeMode: boolean;
    };

    indicators: {
      vwap: boolean;
      atr: boolean;
      volume: boolean;
      momentum: boolean;
    };
  };
}

export interface BrainActor extends CognitiveActor {
  type: "analyzer";
  properties: CognitiveActor["properties"] & {
    reads: ["things", "connections"];  // State + SignalEdge
    writes: ["things"];                // Produces Signal

    config: {
      edgeCacheSize: number;
      precursorPatterns: number;       // 22 GPU-trained patterns
      minPheromone: number;
      minConfidence: number;
    };

    analysis: {
      pheromoneWeight: number;         // 0-1
      regimeWeight: number;
      precursorWeight: number;
    };
  };
}

export interface JudgeActor extends CognitiveActor {
  type: "judge";
  properties: CognitiveActor["properties"] & {
    reads: ["things"];     // Signal
    writes: ["events"];    // Decision

    judgeType: "skeptic" | "mechanist" | "governor";

    config: {
      // Skeptic config
      minConfidence?: number;
      minSources?: number;

      // Mechanist config
      maxSpread?: number;
      minLiquidity?: number;

      // Governor config
      maxDailyLoss?: number;
      maxPosition?: number;
      maxDrawdown?: number;
    };
  };
}

export interface ExecutorActor extends CognitiveActor {
  type: "executor";
  properties: CognitiveActor["properties"] & {
    reads: ["events"];     // Decision
    writes: ["events"];    // Trade

    config: {
      preSignedOrders: boolean;
      maxSlippage: number;
      orderTimeout: number;
      retryAttempts: number;
    };

    exchange: {
      connected: boolean;
      latencyMs: number;
      lastOrderId: string;
    };
  };
}

export interface MemoryActor extends CognitiveActor {
  type: "learner";
  properties: CognitiveActor["properties"] & {
    reads: ["things", "events"];           // State, Signal, Decision, Trade
    writes: ["connections", "knowledge"];  // SignalEdge, Pattern

    config: {
      depositBatchSize: number;
      crystallizationThreshold: number;
      decayRate: number;
      predictionHorizons: number[];  // [60, 300, 900, 3600, 14400, 86400]
    };

    learning: {
      pendingDeposits: number;
      pendingPredictions: number;
      crystallizationCandidates: number;
    };
  };
}

export interface GuardActor extends CognitiveActor {
  type: "guard";
  properties: CognitiveActor["properties"] & {
    reads: ["events"];
    writes: [];  // Guard only blocks, doesn't write

    limits: {
      maxDailyLoss: number;        // 0.03 = 3%
      maxPosition: number;         // 0.30 = 30%
      maxOrdersPerMinute: number;  // 10
      maxConsecutiveLosses: number; // 5
    };

    state: {
      dailyPnL: number;
      ordersThisMinute: number;
      consecutiveLosses: number;
      halted: boolean;
      haltReason?: string;
    };
  };
}

Pydantic Models

# ants/trader/models/actors.py
# ONE Dimension: ACTORS

from enum import Enum
from typing import List, Optional
from pydantic import Field

class CognitiveActorType(str, Enum):
    ORCHESTRATOR = "orchestrator"
    PERCEIVER = "perceiver"
    ANALYZER = "analyzer"
    JUDGE = "judge"
    EXECUTOR = "executor"
    LEARNER = "learner"
    GUARD = "guard"

class ActorState(TraderModel):
    """Runtime state of an actor."""
    connected: bool = False
    healthy: bool = True
    last_activity: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    error_count: int = 0

class CognitiveActor(TraderModel):
    """
    Base cognitive actor in the trading mind.

    ONE Dimension: ACTORS
    TypeDB Entity: cognitive-actor (extends ai-agent)
    """
    actor_id: str
    actor_type: CognitiveActorType
    name: str

    reads: List[Dimension] = []
    writes: List[Dimension] = []

    state: ActorState = Field(default_factory=ActorState)

    @classmethod
    def dimension(cls) -> Dimension:
        return "actors"

class RealtimeGuard(TraderModel):
    """
    Kill switches and rate limits.

    ONE Dimension: ACTORS (agent-subtype: "guard")
    """
    max_daily_loss: float = Field(default=0.03)           # 3%
    max_position: float = Field(default=0.30)             # 30%
    max_orders_per_minute: int = Field(default=10)
    max_consecutive_losses: int = Field(default=5)

    # State
    daily_pnl: float = 0
    orders_this_minute: int = 0
    consecutive_losses: int = 0
    halted: bool = False
    halt_reason: str = ""

    def check(self, decision: "Decision", current_position: float) -> tuple[bool, str]:
        """Check all kill switches."""
        if self.halted:
            return False, self.halt_reason

        if self.daily_pnl <= -self.max_daily_loss:
            self.halted = True
            self.halt_reason = "daily_loss_limit"
            return False, self.halt_reason

        if self.consecutive_losses >= self.max_consecutive_losses:
            self.halted = True
            self.halt_reason = "consecutive_losses"
            return False, self.halt_reason

        if current_position + decision.size > self.max_position:
            return False, "position_limit"

        if self.orders_this_minute >= self.max_orders_per_minute:
            return False, "rate_limit"

        return True, "ok"

    @classmethod
    def dimension(cls) -> Dimension:
        return "actors"

TypeDB Schema

# ONE Dimension: ACTORS
# TypeDB Entity: cognitive-actor

define

cognitive-actor sub ai-agent,
    owns actor-type,
    owns reads-dimensions,
    owns writes-dimensions,
    owns is-connected,
    owns is-healthy,
    owns last-activity,
    owns error-count;

trading-guard sub cognitive-actor,
    owns max-daily-loss,
    owns max-position,
    owns max-orders-per-minute,
    owns max-consecutive-losses,
    owns daily-pnl,
    owns orders-this-minute,
    owns consecutive-losses,
    owns is-halted,
    owns halt-reason;

DIMENSION 3: THINGS (Market Observables)

"Things are passive entities that can be observed and measured." — ONE Ontology

The OBSERVE layer perceives the market and produces Thing entities.

TypeScript Types

// ants/trader/types/things.ts (ASPIRATIONAL - for future frontend)

export type RegimeType =
  | "trending_up"
  | "trending_down"
  | "ranging"
  | "volatile"
  | "crash"
  | "unknown";

export type Direction = "long" | "short" | "neutral";

export interface Price {
  symbol: string;
  timestamp: Date;
  bid: number;
  ask: number;
  last: number;
  open: number;
  high: number;
  low: number;
  close: number;
  volume: number;

  // Computed
  mid: number;           // (bid + ask) / 2
  spread: number;        // ask - bid
  spreadBps: number;     // spread in basis points
}

export interface Depth {
  timestamp: Date;
  bidPrice: number;
  askPrice: number;
  bidSize: number;
  askSize: number;
  bidDepth10: number;    // Depth at 10 levels
  askDepth10: number;

  // Computed
  imbalance: number;     // (bid - ask) / (bid + ask), range -1 to 1
}

export interface Volatility {
  timestamp: Date;
  atr14: number;
  atrPct: number;        // ATR as percentage of price
  rv24h: number;         // 24h realized volatility
  volPercentile: number; // 0-1, historical percentile

  // Computed
  regime: "extreme" | "high" | "normal" | "low";
}

export interface Funding {
  timestamp: Date;
  symbol: string;
  fundingRate: number;
  predictedFunding: number;
  openInterest: number;
  oiChangePct: number;

  // Computed
  fundingSignal: "very_long" | "long" | "neutral" | "short" | "very_short";
}

export interface Regime {
  timestamp: Date;
  regimeType: RegimeType;
  confidence: number;     // 0-1
  transitionProb: number; // Probability of regime change

  // Multi-timeframe alignment
  alignment1h: RegimeType;
  alignment4h: RegimeType;
  alignment1d: RegimeType;

  // Computed
  alignmentScore: number; // 0-1, how aligned are timeframes
}

export interface State {
  stateId: string;
  timestamp: Date;
  symbol: string;

  // Sub-observations (all optional for partial states)
  price?: Price;
  depth?: Depth;
  volatility?: Volatility;
  funding?: Funding;
  regime?: Regime;

  // Computed
  discretized: string;    // e.g., "UP2:HVOL:TREN:LONG"
  completeness: number;   // 0-1, fraction of observations present
}

export interface Signal {
  signalId: string;
  stateId: string;        // Links to State
  timestamp: Date;

  // Core signal
  direction: Direction;
  strength: number;       // 0-1, how strong
  confidence: number;     // 0-1, how sure

  // Alpha sources that contributed
  sources: Record<string, number>;

  // Entry targets (optional)
  suggestedEntry?: number;
  suggestedStop?: number;
  suggestedTarget?: number;

  // Reasoning
  reasoning: string;
  primaryDriver: string;

  // Computed
  isActionable: boolean;
  sourceAlignment: number;
}

// Trading-specific THINGS

export interface PrecursorIndicator {
  indicatorId: string;
  timestamp: Date;

  patternType: string;    // e.g., "volume_breakout_low"
  threshold: number;
  currentValue: number;
  triggered: boolean;

  // Historical accuracy
  accuracy: number;       // 0-1
  sampleSize: number;
  avgWarningCandles: number;

  // Pheromone level from GPU training
  pheromoneLevel: number; // 0-1
}

export interface RegimeSnapshot {
  snapshotId: string;
  timestamp: Date;

  currentRegime: RegimeType;
  regimeDuration: number;  // Hours in current regime

  // Precursor signals
  activePrecursors: PrecursorIndicator[];

  // Transition prediction
  predictedNextRegime?: RegimeType;
  transitionConfidence: number;
  estimatedCandlesToTransition?: number;
}

Pydantic Models

# ants/trader/models/things.py
# ONE Dimension: THINGS

from enum import Enum
from typing import Optional, Dict, List
from pydantic import Field, computed_field

class RegimeType(str, Enum):
    TRENDING_UP = "trending_up"
    TRENDING_DOWN = "trending_down"
    RANGING = "ranging"
    VOLATILE = "volatile"
    CRASH = "crash"
    UNKNOWN = "unknown"

class Direction(str, Enum):
    LONG = "long"
    SHORT = "short"
    NEUTRAL = "neutral"

class Price(TraderModel):
    """
    Price observation.
    ONE Dimension: THINGS (sub-observation of State)
    """
    symbol: str
    timestamp: datetime
    bid: float = Field(ge=0)
    ask: float = Field(ge=0)
    last: float = Field(ge=0)
    open: float = Field(ge=0)
    high: float = Field(ge=0)
    low: float = Field(ge=0)
    close: float = Field(ge=0)
    volume: float = Field(ge=0)

    @computed_field
    @property
    def mid(self) -> float:
        return (self.bid + self.ask) / 2

    @computed_field
    @property
    def spread(self) -> float:
        return self.ask - self.bid

    @computed_field
    @property
    def spread_bps(self) -> float:
        if self.mid == 0:
            return 0
        return (self.spread / self.mid) * 10000

    @classmethod
    def dimension(cls) -> Dimension:
        return "things"

class Depth(TraderModel):
    """
    Order book observation.
    ONE Dimension: THINGS (sub-observation of State)
    """
    timestamp: datetime
    bid_price: float
    ask_price: float
    bid_size: float = Field(ge=0)
    ask_size: float = Field(ge=0)
    bid_depth_10: float = Field(ge=0, default=0)
    ask_depth_10: float = Field(ge=0, default=0)

    @computed_field
    @property
    def imbalance(self) -> float:
        total = self.bid_size + self.ask_size
        if total == 0:
            return 0
        return (self.bid_size - self.ask_size) / total

    @classmethod
    def dimension(cls) -> Dimension:
        return "things"

class Volatility(TraderModel):
    """
    Volatility observation.
    ONE Dimension: THINGS (sub-observation of State)
    """
    timestamp: datetime
    atr_14: float = Field(ge=0, default=0)
    atr_pct: float = Field(ge=0, default=0)
    rv_24h: float = Field(ge=0, default=0)
    vol_percentile: float = Field(ge=0, le=1, default=0.5)

    @computed_field
    @property
    def regime(self) -> str:
        if self.vol_percentile > 0.8:
            return "extreme"
        elif self.vol_percentile > 0.6:
            return "high"
        elif self.vol_percentile < 0.2:
            return "low"
        return "normal"

    @classmethod
    def dimension(cls) -> Dimension:
        return "things"

class Funding(TraderModel):
    """
    Funding rate observation.
    ONE Dimension: THINGS (sub-observation of State)
    """
    timestamp: datetime
    symbol: str
    funding_rate: float = 0
    predicted_funding: float = 0
    open_interest: float = Field(ge=0, default=0)
    oi_change_pct: float = 0

    @computed_field
    @property
    def funding_signal(self) -> str:
        if self.funding_rate > 0.001:
            return "very_long"
        elif self.funding_rate > 0.0003:
            return "long"
        elif self.funding_rate < -0.001:
            return "very_short"
        elif self.funding_rate < -0.0003:
            return "short"
        return "neutral"

    @classmethod
    def dimension(cls) -> Dimension:
        return "things"

class RegimeObservation(TypeDBModel):
    """
    Multi-timeframe regime observation with alignment scoring.

    ONE Dimension: THINGS (sub-observation of State)
    TypeDB Entity: regime-observation

    Note: Uses str for flexibility (can be any regime value).
    """
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    regime_type: str = Field(default="unknown", description="Current regime from Regime enum")
    confidence: float = Field(ge=0, le=1, default=0)
    transition_prob: float = Field(ge=0, le=1, default=0)

    # Multi-timeframe alignment (for confluence)
    alignment_1h: str = Field(default="unknown")
    alignment_4h: str = Field(default="unknown")
    alignment_1d: str = Field(default="unknown")

    @computed_field
    @property
    def alignment_score(self) -> float:
        """Fraction of timeframes in agreement (0-1)."""
        regimes = [self.regime_type, self.alignment_1h, self.alignment_4h, self.alignment_1d]
        regimes = [r for r in regimes if r != "unknown"]
        if not regimes:
            return 0
        from collections import Counter
        most_common = Counter(regimes).most_common(1)[0][1]
        return most_common / len(regimes)

    @classmethod
    def dimension(cls) -> Dimension:
        return "things"

class State(TraderModel):
    """
    Unified market state - the primary THING in trading.

    ONE Dimension: THINGS
    TypeDB Entity: market-state
    Cognitive Layer: OBSERVE output
    """
    state_id: str = ""
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    symbol: str = "BTC-PERP"

    price: Optional[Price] = None
    depth: Optional[Depth] = None
    volatility: Optional[Volatility] = None
    funding: Optional[Funding] = None
    regime: Optional[Regime] = None

    def model_post_init(self, __context) -> None:
        if not self.state_id:
            self.state_id = self._generate_id()

    def _generate_id(self) -> str:
        data = f"{self.symbol}:{self.timestamp.isoformat()}"
        return hashlib.sha256(data.encode()).hexdigest()[:16]

    @computed_field
    @property
    def discretized(self) -> str:
        """Discretized state for pheromone edge lookup."""
        parts = []
        if self.price:
            change = (self.price.close - self.price.open) / self.price.open if self.price.open else 0
            if change > 0.02: parts.append("UP2")
            elif change > 0.005: parts.append("UP1")
            elif change < -0.02: parts.append("DN2")
            elif change < -0.005: parts.append("DN1")
            else: parts.append("FLAT")
        if self.volatility:
            parts.append(self.volatility.regime[:4].upper())
        if self.regime:
            parts.append(self.regime.regime_type.value[:4].upper())
        if self.funding:
            parts.append(self.funding.funding_signal[:4].upper())
        return ":".join(parts) if parts else "UNKNOWN"

    @computed_field
    @property
    def completeness(self) -> float:
        fields = [self.price, self.depth, self.volatility, self.funding, self.regime]
        return sum(1 for f in fields if f is not None) / len(fields)

    @classmethod
    def dimension(cls) -> Dimension:
        return "things"

class Signal(TraderModel):
    """
    Trading signal - output of analysis.

    ONE Dimension: THINGS (analysis result, observable)
    Cognitive Layer: ANALYZE output, DECIDE input
    """
    signal_id: str = ""
    state_id: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    direction: Direction = Direction.NEUTRAL
    strength: float = Field(ge=0, le=1, default=0)
    confidence: float = Field(ge=0, le=1, default=0)
    sources: Dict[str, float] = Field(default_factory=dict)

    suggested_entry: Optional[float] = None
    suggested_stop: Optional[float] = None
    suggested_target: Optional[float] = None

    reasoning: str = ""
    primary_driver: str = ""

    def model_post_init(self, __context) -> None:
        if not self.signal_id:
            data = f"{self.state_id}:{self.timestamp.isoformat()}:{self.direction.value}"
            self.signal_id = hashlib.sha256(data.encode()).hexdigest()[:16]

    @computed_field
    @property
    def is_actionable(self) -> bool:
        return (
            self.direction != Direction.NEUTRAL
            and self.strength >= 0.3
            and self.confidence >= 0.5
        )

    @computed_field
    @property
    def source_alignment(self) -> float:
        if not self.sources:
            return 0
        positive = sum(1 for v in self.sources.values() if v > 0)
        negative = sum(1 for v in self.sources.values() if v < 0)
        total = positive + negative
        if total == 0:
            return 0
        return max(positive, negative) / total

    @classmethod
    def dimension(cls) -> Dimension:
        return "things"

class PrecursorIndicator(TraderModel):
    """
    Precursor pattern indicator for regime transition detection.

    ONE Dimension: THINGS
    TypeDB Entity: precursor-indicator

    Field names match TypeQL schema (kebab-case → snake_case):
    - threshold-value → threshold_value
    - is-triggered → is_triggered
    """
    indicator_id: str
    timestamp: datetime

    # Pattern detection (TypeQL: pattern-type, threshold-value, current-value, is-triggered)
    pattern_type: str
    threshold_value: float
    current_value: float
    is_triggered: bool = False

    # Statistics (TypeQL: accuracy, sample-size, avg-warning-candles, pheromone-level)
    accuracy: float = Field(ge=0, le=1, default=0.5)
    sample_size: int = Field(ge=0, default=0)
    avg_warning_candles: float = Field(ge=0, default=2.0)
    pheromone_level: float = Field(ge=0, le=1, default=0.5)

    @classmethod
    def dimension(cls) -> Dimension:
        return "things"

TypeDB Schema

# ONE Dimension: THINGS
# TypeDB 3.0 Syntax (PERA Model)
# Entities: market-state, trading-signal, precursor-indicator

define

# === ATTRIBUTE TYPES (Algebraic Types) ===
attribute state-id, value string;
attribute signal-id, value string;
attribute indicator-id, value string;
attribute symbol, value string;
attribute timestamp, value datetime;
attribute discretized-state, value string;
attribute completeness, value double;
attribute price-bid, value double;
attribute price-ask, value double;
attribute price-last, value double;
attribute price-volume, value double;
attribute depth-imbalance, value double;
attribute vol-atr-pct, value double;
attribute vol-percentile, value double;
attribute vol-regime, value string;
attribute funding-rate, value double;
attribute funding-signal, value string;
attribute regime-type, value string;
attribute regime-confidence, value double;
attribute regime-alignment, value double;
attribute signal-direction, value string;
attribute signal-strength, value double;
attribute signal-confidence, value double;
attribute suggested-entry, value double;
attribute suggested-stop, value double;
attribute suggested-target, value double;
attribute signal-reasoning, value string;
attribute primary-driver, value string;
attribute is-actionable, value boolean;
attribute source-alignment, value double;
attribute pattern-type, value string;
attribute threshold-value, value double;
attribute current-value, value double;
attribute is-triggered, value boolean;
attribute accuracy, value double;
attribute sample-size, value integer;
attribute avg-warning-candles, value double;
attribute pheromone-level, value double;

# === ENTITY TYPES (Independent Types) ===

entity market-state,
    owns state-id @key,
    owns symbol @card(1),
    owns timestamp @card(1),
    owns discretized-state,
    owns completeness,
    owns price-bid,
    owns price-ask,
    owns price-last,
    owns price-volume,
    owns depth-imbalance,
    owns vol-atr-pct,
    owns vol-percentile,
    owns vol-regime,
    owns funding-rate,
    owns funding-signal,
    owns regime-type,
    owns regime-confidence,
    owns regime-alignment;

entity trading-signal,
    owns signal-id @key,
    owns state-id @card(1),
    owns timestamp @card(1),
    owns signal-direction @card(1),
    owns signal-strength,
    owns signal-confidence,
    owns suggested-entry,
    owns suggested-stop,
    owns suggested-target,
    owns signal-reasoning,
    owns primary-driver,
    owns is-actionable,
    owns source-alignment;

entity precursor-indicator,
    owns indicator-id @key,
    owns timestamp @card(1),
    owns pattern-type @card(1),
    owns threshold-value,
    owns current-value,
    owns is-triggered,
    owns accuracy,
    owns sample-size,
    owns avg-warning-candles,
    owns pheromone-level;

DIMENSION 4: CONNECTIONS (Pheromone Trails)

"Connections encode relationships with cost - the basis of stigmergy." — ONE Ontology

The ANALYZE layer queries pheromone edges (CONNECTIONS) to generate signals.

TypeScript Types

// ants/trader/types/connections.ts (ASPIRATIONAL)

export type EdgeTier = "elite" | "promising" | "neutral" | "danger";

export interface SignalEdge {
  edgeId: string;
  fromStateId: string;      // Discretized state
  toDirection: Direction;   // Target action

  // Raw counts
  winCount: number;
  lossCount: number;
  totalPnl: number;

  // Timestamps
  createdAt: Date;
  updatedAt: Date;

  // Tier (can be INFERRED by TypeDB rules)
  tier?: EdgeTier;

  // Computed
  totalTrades: number;
  winRate: number;
  avgPnl: number;
  trailPheromone: number;   // 0-100, positive reinforcement
  alarmPheromone: number;   // 0-100, negative reinforcement
  effectiveCost: number;    // STAN cost: lower = better
  isSuperhighway: boolean;
}

// Trading-specific CONNECTIONS

export interface RegimeTransition {
  transitionId: string;
  fromRegime: RegimeType;
  toRegime: RegimeType;
  timestamp: Date;

  // Precursor context
  precursorPatterns: string[];
  precursorLeadTime: number;  // Candles before transition

  // Outcome
  priceChangeAfter: number;
  durationCandles: number;
  confidence: number;

  // Pheromone strength
  pheromoneLevel: number;
}

export interface PatternCorrelation {
  correlationId: string;
  patternA: string;
  patternB: string;

  // Correlation metrics
  cooccurrence: number;      // How often they appear together
  sequenceProbability: number; // P(B | A)
  synergy: number;           // Combined accuracy vs individual

  // Usage
  observationCount: number;
  lastObserved: Date;
}

export interface IndicatorDependency {
  dependencyId: string;
  sourceIndicator: string;
  targetIndicator: string;

  // Dependency type
  type: "leads" | "confirms" | "contradicts";
  lagCandles: number;
  correlation: number;

  // Reliability
  reliability: number;       // 0-1
  sampleSize: number;
}

Pydantic Models

# ants/trader/models/connections.py
# ONE Dimension: CONNECTIONS

from typing import Optional, List
from pydantic import Field, computed_field

class SignalEdge(TypeDBModel):
    """
    Pheromone edge - the fundamental CONNECTION in trading.

    ONE Dimension: CONNECTIONS
    TypeDB Entity: signal-edge
    Role: Links discretized state → direction with pheromone cost
    """
    edge_id: str = Field(default_factory=lambda: f"edge:{uuid4().hex[:8]}")
    symbol_name: str = Field(default="BTC-PERP", description="Trading symbol")
    from_state_id: str = Field(..., description="Source state (discretized)")
    to_signal_direction: str = Field(..., description="Target direction: bullish/bearish/neutral")
    to_direction: str = Field(default="", description="Alias for to_signal_direction")

    win_count: int = Field(ge=0, default=0)
    loss_count: int = Field(ge=0, default=0)
    total_pnl: float = 0

    # Pheromone levels
    trail_pheromone: float = Field(default=0.5, ge=0, le=100)
    alarm_pheromone: float = Field(default=0.0, ge=0, le=100)
    quality_pheromone: float = Field(default=0.5, ge=0, le=100)

    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    tier: Optional[str] = None

    @computed_field
    @property
    def total_trades(self) -> int:
        return self.win_count + self.loss_count

    @computed_field
    @property
    def win_rate(self) -> float:
        if self.total_trades == 0:
            return 0.5
        return self.win_count / self.total_trades

    @computed_field
    @property
    def avg_pnl(self) -> float:
        if self.total_trades == 0:
            return 0
        return self.total_pnl / self.total_trades

    @computed_field
    @property
    def trail_pheromone(self) -> float:
        """Positive reinforcement signal (0-100)."""
        BASE = 50.0
        if self.total_trades < 10:
            return BASE
        wr_component = (self.win_rate - 0.5) * 2 * 40
        pnl_norm = max(-1, min(1, self.avg_pnl / 5.0))
        pnl_component = pnl_norm * 10
        return max(0.01, min(100, BASE + wr_component + pnl_component))

    @computed_field
    @property
    def alarm_pheromone(self) -> float:
        """Danger signal (0-100)."""
        if self.total_trades < 10 or self.win_rate >= 0.5:
            return 0
        alarm = (0.5 - self.win_rate) * 2 * 60
        if self.avg_pnl < -2.0:
            alarm += abs(self.avg_pnl) * 5
        return min(100, alarm)

    @computed_field
    @property
    def effective_cost(self) -> float:
        """STAN effective cost: lower = better path."""
        pheromone_level = self.trail_pheromone - self.alarm_pheromone
        return 1.0 / (1 + pheromone_level * 0.1)

    @computed_field
    @property
    def is_superhighway(self) -> bool:
        """High-traffic proven path (KNOWLEDGE candidate)."""
        return self.trail_pheromone >= 85 and self.total_trades >= 100

    # === BAYESIAN CONFIDENCE (NEW) ===

    @computed_field
    @property
    def beta_alpha(self) -> float:
        """Beta distribution alpha parameter (wins + prior)."""
        return self.win_count + 1  # Uniform prior

    @computed_field
    @property
    def beta_beta(self) -> float:
        """Beta distribution beta parameter (losses + prior)."""
        return self.loss_count + 1  # Uniform prior

    @computed_field
    @property
    def win_rate_mean(self) -> float:
        """Bayesian mean of win rate."""
        return self.beta_alpha / (self.beta_alpha + self.beta_beta)

    @computed_field
    @property
    def win_rate_confidence_95(self) -> tuple[float, float]:
        """
        95% credible interval for win rate.

        This is THE key metric for avoiding overfitting:
        - Edge with 3/4 wins: CI = (0.32, 0.98) — wide, uncertain
        - Edge with 75/100 wins: CI = (0.66, 0.83) — narrow, reliable

        Don't trade edges with wide CIs!
        """
        from scipy.stats import beta
        dist = beta(self.beta_alpha, self.beta_beta)
        return (dist.ppf(0.025), dist.ppf(0.975))

    @computed_field
    @property
    def confidence_width(self) -> float:
        """Width of 95% CI. Narrower = more reliable."""
        ci = self.win_rate_confidence_95
        return ci[1] - ci[0]

    @computed_field
    @property
    def is_statistically_significant(self) -> bool:
        """
        Is this edge reliably different from random (50%)?

        True if: lower bound of 95% CI > 0.5 (for winners)
                 OR upper bound of 95% CI < 0.5 (for losers)
        """
        ci = self.win_rate_confidence_95
        return ci[0] > 0.5 or ci[1] < 0.5

    @computed_field
    @property
    def sample_size_needed(self) -> int:
        """
        Approximate trades needed for CI width < 0.1.

        Wilson score CI width ≈ 2 * 1.96 * sqrt(p*(1-p)/n)
        For width = 0.1 and p = 0.5: n ≈ 385
        """
        if self.confidence_width < 0.1:
            return 0
        # Rough estimate
        return max(0, 400 - self.total_trades)

    @classmethod
    def dimension(cls) -> Dimension:
        return "connections"

class RegimeTransition(TypeDBModel):
    """
    Regime transition with precursor context.

    ONE Dimension: CONNECTIONS
    TypeDB Entity: regime-transition
    """
    transition_id: str = Field(default_factory=lambda: f"trans:{uuid4().hex[:8]}")
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    from_regime: str = Field(..., description="Previous regime")
    to_regime: str = Field(..., description="New regime")

    precursor_patterns: List[str] = Field(default_factory=list, description="Patterns that fired before transition")
    precursor_lead_time: float = Field(default=0.0, ge=0, description="Candles between pattern fire and transition")

    @classmethod
    def dimension(cls) -> Dimension:
        return "connections"

class PatternCorrelation(TypeDBModel):
    """
    Correlation between patterns.

    ONE Dimension: CONNECTIONS
    TypeDB Entity: pattern-correlation
    """
    correlation_id: str = Field(default_factory=lambda: f"corr:{uuid4().hex[:8]}")
    pattern_a: str = Field(..., description="First pattern name")
    pattern_b: str = Field(..., description="Second pattern name")

    cooccurrence: int = Field(ge=0, default=0, description="Times both fired together")
    sequence_probability: float = Field(ge=0, le=1, default=0.5, description="P(B|A)")
    synergy: float = Field(ge=-1, le=1, default=0.0, description="Combined effect vs individual")

    observation_count: int = Field(ge=0, default=0, description="Total observations")
    last_observed: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    @classmethod
    def dimension(cls) -> Dimension:
        return "connections"

TypeDB Schema

# ONE Dimension: CONNECTIONS
# TypeDB 3.0 Syntax (PERA Model)
# Entities: signal-edge, regime-transition, pattern-correlation

define

# === ATTRIBUTE TYPES (Algebraic Types) ===
attribute edge-id, value string;
attribute from-state-id, value string;
attribute to-signal-direction, value string;
attribute win-count, value integer;
attribute loss-count, value integer;
attribute total-pnl, value double;
attribute trail-pheromone, value double;
attribute alarm-pheromone, value double;
attribute quality-pheromone, value double;
attribute edge-win-rate, value double;
attribute edge-strength, value double;
attribute tier, value string;
attribute is-superhighway, value boolean;
attribute crystallization-ready, value boolean;
attribute beta-alpha, value double;
attribute beta-beta, value double;
attribute win-rate-ci-lower, value double;
attribute win-rate-ci-upper, value double;
attribute confidence-width, value double;
attribute is-statistically-significant, value boolean;
attribute sample-size-needed, value integer;
attribute created-at, value datetime;
attribute updated-at, value datetime;
attribute transition-id, value string;
attribute from-regime, value string;
attribute to-regime, value string;
attribute precursor-patterns, value string;
attribute precursor-lead-time, value double;
attribute price-change-after, value double;
attribute duration-candles, value integer;
attribute correlation-id, value string;
attribute pattern-a, value string;
attribute pattern-b, value string;
attribute cooccurrence, value double;
attribute sequence-probability, value double;
attribute synergy, value double;
attribute observation-count, value integer;
attribute last-observed, value datetime;

# === ENTITY TYPES (Independent Types) ===

entity signal-edge,
    owns edge-id @key,
    owns from-state-id @card(1),
    owns to-signal-direction @card(1),
    owns win-count @card(1),
    owns loss-count @card(1),
    owns total-pnl,
    owns trail-pheromone,
    owns alarm-pheromone,
    owns quality-pheromone,
    owns edge-win-rate,
    owns edge-strength,
    owns tier,
    owns is-superhighway,
    owns crystallization-ready,
    # Bayesian confidence
    owns beta-alpha,
    owns beta-beta,
    owns win-rate-ci-lower,
    owns win-rate-ci-upper,
    owns confidence-width,
    owns is-statistically-significant,
    owns sample-size-needed,
    owns created-at @card(1),
    owns updated-at;

entity regime-transition,
    owns transition-id @key,
    owns from-regime @card(1),
    owns to-regime @card(1),
    owns timestamp @card(1),
    owns precursor-patterns,
    owns precursor-lead-time,
    owns price-change-after,
    owns duration-candles,
    owns confidence,
    owns pheromone-level;

entity pattern-correlation,
    owns correlation-id @key,
    owns pattern-a @card(1),
    owns pattern-b @card(1),
    owns cooccurrence,
    owns sequence-probability,
    owns synergy,
    owns observation-count,
    owns last-observed;

# === FUNCTIONS (TypeQL 3.0 - Replace Rules) ===

# Elite pattern detection: high win rate, high pheromone, sufficient trades
fun get_elite_edges() -> { signal-edge }:
    match
        $e isa signal-edge,
            has edge-win-rate $wr,
            has trail-pheromone $tp,
            has win-count $wc,
            has loss-count $lc;
        let $total = $wc + $lc;
        $wr >= 0.75;
        $tp >= 70.0;
        $total >= 50;
    return { $e };

# Danger zone detection: low win rate, high alarm signal
fun get_danger_edges() -> { signal-edge }:
    match
        $e isa signal-edge,
            has edge-win-rate $wr,
            has alarm-pheromone $ap,
            has win-count $wc,
            has loss-count $lc;
        let $total = $wc + $lc;
        $wr < 0.40;
        $ap >= 25.0;
        $total >= 30;
    return { $e };

# Superhighway detection: heavily trafficked, proven paths
fun get_superhighways() -> { signal-edge }:
    match
        $e isa signal-edge,
            has trail-pheromone $tp,
            has win-count $wc,
            has loss-count $lc;
        let $total = $wc + $lc;
        $tp >= 85.0;
        $total >= 100;
    return { $e };

# Crystallization candidates: elite patterns ready for permanent storage
fun get_crystallization_candidates() -> { signal-edge }:
    match
        $e in get_elite_edges();
        $e has trail-pheromone $tp,
           has win-count $wc,
           has loss-count $lc;
        let $total = $wc + $lc;
        $tp >= 80.0;
        $total >= 100;
    return { $e };

# Check if an edge is elite (scalar function)
fun is_elite($e: signal-edge) -> boolean:
    match
        $e has edge-win-rate $wr,
           has trail-pheromone $tp,
           has win-count $wc,
           has loss-count $lc;
        let $total = $wc + $lc;
        $wr >= 0.75;
        $tp >= 70.0;
        $total >= 50;
    return true;

# Calculate STAN effective cost
fun stan_cost($e: signal-edge, $alpha: double = 0.7) -> double:
    match
        $e has trail-pheromone $tp,
           has alarm-pheromone $ap;
        let $pheromone = $tp - $ap;
    return 1.0 / (1.0 + $pheromone * $alpha);

# Aggregate colony statistics
fun colony_stats() -> { integer, integer, double }:
    match
        $e isa signal-edge,
            has win-count $wc,
            has loss-count $lc;
    reduce
        $total_wins = sum($wc),
        $total_losses = sum($lc);
    let $win_rate = $total_wins / ($total_wins + $total_losses);
    return { $total_wins, $total_losses, $win_rate };

DIMENSION 5: EVENTS (Trading Actions)

"Events record what happened - the immutable history of the colony." — ONE Ontology

The DECIDE and ACT layers produce Event entities.

TypeScript Types

// ants/trader/types/events.ts (ASPIRATIONAL)

export type TradeOutcome = "win" | "loss" | "breakeven" | "pending";

export interface JudgeVerdict {
  judge: "skeptic" | "mechanist" | "governor";
  approved: boolean;
  confidence: number;
  reason: string;
  concerns: string[];
}

export interface Decision {
  decisionId: string;
  signalId: string;
  timestamp: Date;

  // Core decision
  approved: boolean;
  action: "long" | "short" | "hold" | "close";

  // Position parameters
  size: number;           // Fraction of equity (0-1)
  entry: number;
  stop: number;
  target: number;

  // Judge verdicts
  skeptic?: JudgeVerdict;
  mechanist?: JudgeVerdict;
  governor?: JudgeVerdict;

  // Reasoning
  reason: string;
  concerns: string[];

  // Computed
  allApproved: boolean;
  riskReward: number;
}

export interface Trade {
  tradeId: string;
  decisionId: string;
  timestamp: Date;

  // Execution
  orderId: string;
  symbol: string;
  side: "buy" | "sell";
  size: number;
  filledPrice: number;
  filledSize: number;

  // Quality metrics
  slippageBps: number;
  latencyMs: number;

  // Outcome (filled after exit)
  exitPrice?: number;
  exitTime?: Date;
  pnl: number;
  pnlPct: number;
  outcome: TradeOutcome;
}

// Trading-specific EVENTS

export interface RegimeChangeEvent {
  eventId: string;
  timestamp: Date;

  fromRegime: RegimeType;
  toRegime: RegimeType;

  // Precursor context
  precursorsFired: string[];
  leadTimeCandles: number;

  // Impact
  priceAtTransition: number;
  price1hAfter?: number;
  price4hAfter?: number;

  // Learning
  predictedCorrectly: boolean;
  predictionConfidence: number;
}

export interface PatternDiscoveryEvent {
  eventId: string;
  timestamp: Date;

  patternType: string;
  discoverySource: "gpu_training" | "live_observation" | "hypothesis_test";

  // Pattern details
  accuracy: number;
  sampleSize: number;
  avgLeadTime: number;

  // Significance
  pheromoneLevel: number;
  isNovel: boolean;
}

export interface CrystallizationEvent {
  eventId: string;
  timestamp: Date;

  edgeId: string;
  patternId: string;

  // Edge metrics at crystallization
  winRate: number;
  totalTrades: number;
  totalPnl: number;
  trailPheromone: number;

  // Crystallized knowledge
  confidence: number;
  transferable: boolean;
  targetMissions: string[];
}

export interface PheromoneDecayEvent {
  eventId: string;
  timestamp: Date;

  edgesAffected: number;
  decayRate: number;

  // Stats
  avgPheromoneBeforeDecay: number;
  avgPheromoneAfterDecay: number;
  edgesExpired: number;
}

export interface AdaptiveFilterEvent {
  eventId: string;
  timestamp: Date;

  action: "pause" | "resume";
  rollingWinRate: number;
  threshold: number;

  // Context
  recentTrades: number;
  consecutiveLosses: number;
  reason: string;
}

Pydantic Models

# ants/trader/models/events.py
# ONE Dimension: EVENTS

from typing import Optional, List
from pydantic import Field, computed_field

class JudgeVerdict(TraderModel):
    """
    Individual judge's verdict.
    ONE Dimension: EVENTS (sub-event of Decision)
    """
    judge: str
    approved: bool
    confidence: float = Field(ge=0, le=1)
    reason: str
    concerns: List[str] = Field(default_factory=list)

    @classmethod
    def dimension(cls) -> Dimension:
        return "events"

class Decision(TraderModel):
    """
    Trading decision - an EVENT recording what was decided.

    ONE Dimension: EVENTS
    TypeDB Entity: trading-decision
    Cognitive Layer: DECIDE output, ACT input
    """
    decision_id: str = ""
    signal_id: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    approved: bool = False
    action: str = "hold"

    size: float = Field(ge=0, le=1, default=0)
    entry: float = Field(ge=0, default=0)
    stop: float = Field(ge=0, default=0)
    target: float = Field(ge=0, default=0)

    skeptic: Optional[JudgeVerdict] = None
    mechanist: Optional[JudgeVerdict] = None
    governor: Optional[JudgeVerdict] = None

    reason: str = ""
    concerns: List[str] = Field(default_factory=list)

    def model_post_init(self, __context) -> None:
        if not self.decision_id:
            data = f"{self.signal_id}:{self.timestamp.isoformat()}:{self.action}"
            self.decision_id = hashlib.sha256(data.encode()).hexdigest()[:16]

    @computed_field
    @property
    def all_approved(self) -> bool:
        return all([
            self.skeptic and self.skeptic.approved,
            self.mechanist and self.mechanist.approved,
            self.governor and self.governor.approved,
        ])

    @computed_field
    @property
    def risk_reward(self) -> float:
        if self.entry == 0 or self.stop == 0 or self.target == 0:
            return 0
        risk = abs(self.entry - self.stop)
        reward = abs(self.target - self.entry)
        if risk == 0:
            return 0
        return reward / risk

    @classmethod
    def dimension(cls) -> Dimension:
        return "events"

class TradeRecord(TraderModel):
    """
    Trade execution record - an EVENT recording what happened.

    ONE Dimension: EVENTS
    TypeDB Entity: trade-record
    Cognitive Layer: ACT output, LEARN input

    Field names match TypeQL schema (kebab-case → snake_case):
    - trade-side → trade_side
    - trade-size → trade_size
    - trade-pnl → trade_pnl
    """
    # Identity (TypeQL: trade-id, decision-id, order-id, symbol, timestamp)
    trade_id: str = Field(default_factory=lambda: f"trade:{uuid4().hex[:12]}")
    decision_id: str
    order_id: Optional[str] = None
    symbol: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Trade details (TypeQL: trade-side, trade-size)
    trade_side: str  # "buy" or "sell"
    trade_size: float = Field(ge=0)

    # Execution (TypeQL: filled-price, filled-size, slippage-bps, latency-ms)
    filled_price: Optional[float] = Field(default=None, ge=0)
    filled_size: Optional[float] = Field(default=None, ge=0)
    slippage_bps: Optional[float] = None
    latency_ms: Optional[float] = Field(default=None, ge=0)

    # Exit (TypeQL: exit-price, exit-timestamp)
    exit_price: Optional[float] = Field(default=None, ge=0)
    exit_timestamp: Optional[datetime] = None

    # Outcome (TypeQL: trade-pnl, trade-pnl-pct, trade-outcome)
    trade_pnl: Optional[float] = None
    trade_pnl_pct: Optional[float] = None
    trade_outcome: Optional[str] = None  # "win", "loss", "breakeven"

    def close(self, exit_price: float, exit_time: datetime) -> None:
        """Record trade exit and compute P&L."""
        self.exit_price = exit_price
        self.exit_timestamp = exit_time
        if self.filled_price and self.filled_price > 0 and self.filled_size:
            if self.trade_side == "buy":
                self.trade_pnl_pct = (exit_price - self.filled_price) / self.filled_price
            else:
                self.trade_pnl_pct = (self.filled_price - exit_price) / self.filled_price
            self.trade_pnl = self.trade_pnl_pct * self.filled_size * self.filled_price
            if self.trade_pnl_pct > 0.001:
                self.trade_outcome = "win"
            elif self.trade_pnl_pct < -0.001:
                self.trade_outcome = "loss"
            else:
                self.trade_outcome = "breakeven"

    @classmethod
    def dimension(cls) -> Dimension:
        return "events"

class RegimeChangeEvent(TraderModel):
    """
    Event when market regime changes.

    ONE Dimension: EVENTS
    TypeDB Entity: regime-change-event

    Field names match TypeQL schema (kebab-case → snake_case).
    """
    # Identity (TypeQL: event-id, timestamp)
    event_id: str = Field(default_factory=lambda: f"regime:{uuid4().hex[:12]}")
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Transition (TypeQL: from-regime, to-regime)
    from_regime: str
    to_regime: str

    # Precursors (TypeQL: precursors-fired, lead-time-candles)
    precursors_fired: List[str] = Field(default_factory=list)
    lead_time_candles: Optional[int] = Field(default=None, ge=0)

    # Context (TypeQL: price-at-transition, predicted-correctly, prediction-confidence)
    price_at_transition: Optional[float] = Field(default=None, ge=0)
    predicted_correctly: Optional[bool] = None
    prediction_confidence: Optional[float] = Field(default=None, ge=0, le=1)

    @classmethod
    def dimension(cls) -> Dimension:
        return "events"

class CrystallizationEvent(TraderModel):
    """
    Event when a pattern crystallizes into permanent knowledge.

    ONE Dimension: EVENTS
    TypeDB Entity: crystallization-event

    Field names match TypeQL schema (kebab-case → snake_case).
    """
    # Identity (TypeQL: event-id, timestamp)
    event_id: str = Field(default_factory=lambda: f"crystal:{uuid4().hex[:12]}")
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Source (TypeQL: edge-id, pattern-id)
    edge_id: str
    pattern_id: str

    # Statistics (TypeQL: win-rate, total-trades, total-pnl, trail-pheromone)
    win_rate: float = Field(ge=0, le=1)
    total_trades: int = Field(ge=0)
    total_pnl: float
    trail_pheromone: float

    # Quality (TypeQL: confidence, is-transferable, target-missions)
    confidence: float = Field(ge=0, le=1)
    is_transferable: bool = Field(default=True)
    target_missions: List[str] = Field(default_factory=list)

    @classmethod
    def dimension(cls) -> Dimension:
        return "events"

# === NEW EVENT TYPES FOR EMERGENCE ===

class PredictionEvent(TraderModel):
    """
    A prediction made by the system for later verification.

    ONE Dimension: EVENTS
    TypeDB Entity: prediction-event

    Field names match TypeQL schema (kebab-case → snake_case).
    Enables the Reflective Learning System to track predictions.
    """
    # Identity (TypeQL: event-id, timestamp)
    event_id: str = Field(default_factory=lambda: f"pred:{uuid4().hex[:12]}")
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Prediction details (TypeQL: pattern-id, predicted-direction, predicted-outcome, confidence)
    pattern_id: str
    predicted_direction: str  # "bullish" or "bearish"
    predicted_outcome: str    # Expected outcome
    confidence: float = Field(default=0.5, ge=0, le=1)

    # Context (TypeQL: state-id, regime-at-prediction, volatility-at-prediction)
    state_id: str
    regime_at_prediction: str
    volatility_at_prediction: float = Field(default=0.0, ge=0)

    # Verification (TypeQL: is-verified, actual-outcome, actual-pnl, verification-timestamp)
    is_verified: bool = False
    actual_outcome: Optional[str] = None
    actual_pnl: Optional[float] = None
    verification_timestamp: Optional[datetime] = None

    @classmethod
    def dimension(cls) -> Dimension:
        return "events"

class HaltEvent(TraderModel):
    """
    Trading halt event from RealtimeGuard.

    ONE Dimension: EVENTS
    TypeDB Entity: halt-event

    Records when and why trading was halted. Essential for
    post-mortem analysis and guard tuning.
    """
    event_id: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Halt details
    halt_reason: str  # "daily_loss_limit", "consecutive_losses", "rate_limit", "manual"
    guard_type: str   # "realtime_guard", "security_guard", "manual"

    # Context at halt
    daily_pnl_at_halt: float = 0
    consecutive_losses_at_halt: int = 0
    positions_at_halt: int = 0

    # Recovery (TypeQL: is-resumed, resume-timestamp, halt-duration-seconds, recovery-action)
    is_resumed: bool = False
    resume_timestamp: Optional[datetime] = None
    halt_duration_seconds: Optional[int] = None
    recovery_action: Optional[str] = None

    @classmethod
    def dimension(cls) -> Dimension:
        return "events"

class ReproductionEvent(TypeDBModel):
    """
    Agent reproduction event with lineage tracking.

    ONE Dimension: EVENTS
    TypeDB Entity: reproduction-event

    Records every reproduction for phylogenetic analysis.
    """
    event_id: str = Field(default_factory=lambda: f"repro:{uuid4().hex[:8]}")
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Parent info (TypeQL: parent-genome-id, parent-fitness, parent-generation, parent-trades, parent-pnl)
    parent_genome_id: str = Field(..., description="Parent genome ID")
    parent_fitness: float = Field(..., description="Parent fitness at reproduction")
    parent_generation: int = Field(default=0, ge=0, description="Parent generation number")
    parent_trades: int = Field(default=0, ge=0, description="Parent total trades")
    parent_pnl: float = Field(default=0.0, description="Parent total P&L")

    # Offspring info (TypeQL: offspring-genome-id, offspring-generation)
    offspring_genome_id: str = Field(..., description="Offspring genome ID")
    offspring_generation: int = Field(default=1, ge=0, description="Offspring generation number")

    # Mutations (TypeQL: mutation-rate, mutations-applied, mutation-magnitude)
    mutation_rate: float = Field(default=0.1, ge=0, le=1, description="Mutation rate used")
    mutations_applied: int = Field(default=0, ge=0, description="Number of mutations applied")
    mutation_magnitude: float = Field(default=0.0, ge=0, description="Total magnitude of mutations")

    @classmethod
    def dimension(cls) -> Dimension:
        return "events"

class PhaseTransitionEvent(TraderModel):
    """
    Emergence phase transition event.

    ONE Dimension: EVENTS
    TypeDB Entity: phase-transition-event

    Records when the colony crosses emergence thresholds.
    """
    event_id: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Transition details
    from_phase: str
    to_phase: str

    # Metrics at transition
    pattern_count: int = 0
    superhighway_count: int = 0
    colony_win_rate: float = 0
    emergence_score: float = 0
    cycle_number: int = 0

    # What triggered the transition
    trigger_metric: str  # "patterns", "superhighways", "win_rate", "transfers", etc.
    trigger_value: float = 0
    trigger_threshold: float = 0

    @classmethod
    def dimension(cls) -> Dimension:
        return "events"

class SystemEvent(TraderModel):
    """
    System-level event for debugging and observability.

    ONE Dimension: EVENTS
    TypeDB Entity: system-event

    Records system events like service restarts, config changes,
    TypeDB reconnections, etc.
    """
    event_id: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Event type
    event_type: str  # "service_start", "service_stop", "config_change",
                     # "typedb_reconnect", "error", "warning"
    severity: str = "info"  # "debug", "info", "warning", "error", "critical"

    # Context (TypeQL: service-name, message)
    service_name: str = ""
    message: str = ""

    # Error context (TypeQL: error-type, error-message)
    error_type: Optional[str] = None
    error_message: Optional[str] = None

    @classmethod
    def dimension(cls) -> Dimension:
        return "events"

TypeDB Schema

# ONE Dimension: EVENTS
# TypeDB 3.0 Syntax (PERA Model)
# Entities: trading-decision, trade-record, regime-change-event, etc.

define

# === ATTRIBUTE TYPES (Algebraic Types) ===
attribute decision-id, value string;
attribute event-id, value string;
attribute trade-id, value string;
attribute order-id, value string;
attribute decision-approved, value boolean;
attribute decision-action, value string;
attribute position-size, value double;
attribute entry-price, value double;
attribute stop-price, value double;
attribute target-price, value double;
attribute decision-reason, value string;
attribute risk-reward-ratio, value double;
attribute trade-side, value string;
attribute trade-size, value double;
attribute filled-price, value double;
attribute filled-size, value double;
attribute slippage-bps, value double;
attribute latency-ms, value double;
attribute exit-price, value double;
attribute exit-timestamp, value datetime;
attribute trade-pnl, value double;
attribute trade-pnl-pct, value double;
attribute trade-outcome, value string;
attribute precursors-fired, value string;
attribute lead-time-candles, value double;
attribute price-at-transition, value double;
attribute predicted-correctly, value boolean;
attribute prediction-confidence, value double;
attribute predicted-direction, value string;
attribute predicted-outcome, value string;
attribute regime-at-prediction, value string;
attribute volatility-at-prediction, value double;
attribute is-verified, value boolean;
attribute actual-outcome, value string;
attribute actual-pnl, value double;
attribute verification-timestamp, value datetime;
attribute halt-reason, value string;
attribute guard-type, value string;
attribute daily-pnl-at-halt, value double;
attribute consecutive-losses-at-halt, value integer;
attribute positions-at-halt, value integer;
attribute is-resumed, value boolean;
attribute resume-timestamp, value datetime;
attribute halt-duration-seconds, value double;
attribute recovery-action, value string;
attribute parent-genome-id, value string;
attribute parent-fitness, value double;
attribute parent-generation, value integer;
attribute parent-trades, value integer;
attribute parent-pnl, value double;
attribute offspring-genome-id, value string;
attribute offspring-generation, value integer;
attribute mutations-applied, value string;
attribute mutation-magnitude, value double;
attribute colony-size-at-reproduction, value integer;
attribute avg-fitness-at-reproduction, value double;
attribute from-phase, value string;
attribute to-phase, value string;
attribute trigger-metric, value string;
attribute trigger-value, value double;
attribute trigger-threshold, value double;
attribute event-type, value string;
attribute severity, value string;
attribute service-name, value string;
attribute message, value string;
attribute error-type, value string;
attribute error-message, value string;
attribute is-transferable, value boolean;
attribute target-missions, value string;
attribute total-trades, value integer;

# === ENTITY TYPES (Independent Types) ===

entity trading-decision,
    owns decision-id @key,
    owns signal-id @card(1),
    owns timestamp @card(1),
    owns decision-approved @card(1),
    owns decision-action @card(1),
    owns position-size,
    owns entry-price,
    owns stop-price,
    owns target-price,
    owns decision-reason,
    owns risk-reward-ratio,
    plays trade-execution:executed-decision;

entity trade-record,
    owns trade-id @key,
    owns decision-id @card(1),
    owns order-id,
    owns symbol @card(1),
    owns trade-side @card(1),
    owns trade-size @card(1),
    owns filled-price,
    owns filled-size,
    owns slippage-bps,
    owns latency-ms,
    owns exit-price,
    owns exit-timestamp,
    owns trade-pnl,
    owns trade-pnl-pct,
    owns trade-outcome,
    owns timestamp @card(1),
    plays trade-execution:resulting-trade;

entity regime-change-event,
    owns event-id @key,
    owns timestamp @card(1),
    owns from-regime @card(1),
    owns to-regime @card(1),
    owns precursors-fired,
    owns lead-time-candles,
    owns price-at-transition,
    owns predicted-correctly,
    owns prediction-confidence;

entity crystallization-event,
    owns event-id @key,
    owns timestamp @card(1),
    owns edge-id @card(1),
    owns pattern-id @card(1),
    owns win-rate,
    owns total-trades,
    owns total-pnl,
    owns trail-pheromone,
    owns confidence,
    owns is-transferable,
    owns target-missions;

entity prediction-event,
    owns event-id @key,
    owns timestamp @card(1),
    owns pattern-id @card(1),
    owns predicted-direction @card(1),
    owns predicted-outcome,
    owns confidence,
    owns state-id,
    owns regime-at-prediction,
    owns volatility-at-prediction,
    owns is-verified,
    owns actual-outcome,
    owns actual-pnl,
    owns verification-timestamp;

entity halt-event,
    owns event-id @key,
    owns timestamp @card(1),
    owns halt-reason @card(1),
    owns guard-type @card(1),
    owns daily-pnl-at-halt,
    owns consecutive-losses-at-halt,
    owns positions-at-halt,
    owns is-resumed,
    owns resume-timestamp,
    owns halt-duration-seconds,
    owns recovery-action;

entity reproduction-event,
    owns event-id @key,
    owns timestamp @card(1),
    owns parent-genome-id @card(1),
    owns parent-fitness,
    owns parent-generation,
    owns parent-trades,
    owns parent-pnl,
    owns offspring-genome-id @card(1),
    owns offspring-generation,
    owns mutations-applied,
    owns mutation-magnitude,
    owns colony-size-at-reproduction,
    owns avg-fitness-at-reproduction;

entity phase-transition-event,
    owns event-id @key,
    owns timestamp @card(1),
    owns from-phase @card(1),
    owns to-phase @card(1),
    owns pattern-count,
    owns superhighway-count,
    owns colony-win-rate,
    owns emergence-score,
    owns cycle-number,
    owns trigger-metric,
    owns trigger-value,
    owns trigger-threshold;

entity system-event,
    owns event-id @key,
    owns timestamp @card(1),
    owns event-type @card(1),
    owns severity,
    owns service-name,
    owns message,
    owns error-type,
    owns error-message;

# === RELATION TYPES (Dependent Types) ===

relation trade-execution,
    relates executed-decision @card(1),
    relates resulting-trade @card(1);

# === FUNCTIONS (TypeQL 3.0) ===

# Get recent trades by outcome
fun get_trades_by_outcome($outcome: string, $limit: integer = 50) -> { trade-record }:
    match
        $t isa trade-record,
            has trade-outcome $outcome,
            has timestamp $ts;
    sort $ts desc;
    limit $limit;
    return { $t };

# Get winning trades
fun get_winning_trades($limit: integer = 100) -> { trade-record }:
    match $t in get_trades_by_outcome("win", $limit);
    return { $t };

# Get decisions with their resulting trades
fun get_decision_with_trade($decision_id: string) -> { trading-decision, trade-record }:
    match
        $d isa trading-decision, has decision-id $decision_id;
        ($d, $t) isa trade-execution;
    return { $d, $t };

# Track prediction accuracy
fun prediction_accuracy($pattern: string) -> double:
    match
        $p isa prediction-event,
            has pattern-id $pattern,
            has is-verified true,
            has actual-outcome $actual,
            has predicted-outcome $predicted;
        $actual == $predicted;
    reduce $correct = count;
    match
        $p2 isa prediction-event,
            has pattern-id $pattern,
            has is-verified true;
    reduce $total = count;
    return $correct / $total;

DIMENSION 6: KNOWLEDGE (Crystallized Patterns)

"Knowledge is wisdom that persists across generations." — ONE Ontology

The LEARN layer creates and updates KNOWLEDGE from EVENTS.

TypeScript Types

// ants/trader/types/knowledge.ts (ASPIRATIONAL)

export interface CrystallizedPattern {
  patternId: string;
  sourceEdgeId: string;
  sourceMission: string;

  // Pattern definition
  fromState: string;        // Discretized state
  toDirection: Direction;

  // Performance at crystallization
  winRate: number;
  totalTrades: number;
  totalPnl: number;
  avgPnl: number;

  // Pheromone levels
  trailPheromone: number;
  confidence: number;

  // Transfer
  transferable: boolean;
  transferredTo: string[];
  transferCount: number;

  // Metadata
  crystallizedAt: Date;
  lastVerified: Date;
  stillValid: boolean;
}

export interface TradingRiskProfile {
  profileId: string;
  timestamp: Date;

  dimensions: {
    technical: {
      signalQuality: number;      // 0-100
      edgeReliability: number;    // 0-100
      precursorAccuracy: number;  // 0-100
      regimeStability: number;    // 0-100
    };

    market: {
      liquidityRisk: number;      // 0-100
      volatilityRisk: number;     // 0-100
      spreadRisk: number;         // 0-100
      fundingRisk: number;        // 0-100
    };

    execution: {
      slippageRisk: number;       // 0-100
      latencyRisk: number;        // 0-100
      connectionRisk: number;     // 0-100
      rateLimit Risk: number;     // 0-100
    };

    portfolio: {
      concentrationRisk: number;  // 0-100
      drawdownRisk: number;       // 0-100
      correlationRisk: number;    // 0-100
      leverageRisk: number;       // 0-100
    };
  };

  signals: {
    redFlags: string[];
    yellowFlags: string[];
    strengthIndicators: string[];
  };

  recommendation: {
    positionSize: number;         // Suggested position size
    riskMultiplier: number;       // Adjustment factor
    tradingAllowed: boolean;
  };
}

export interface StrategyAnalytics {
  strategyId: string;
  timestamp: Date;

  metrics: {
    totalTrades: number;
    winRate: number;
    avgWin: number;
    avgLoss: number;
    profitFactor: number;
    sharpeRatio: number;
    sortinoRatio: number;
    maxDrawdown: number;
    recoveryFactor: number;
    calmarRatio: number;
  };

  breakdown: {
    byRegime: Record<RegimeType, {
      trades: number;
      winRate: number;
      pnl: number;
    }>;

    byTimeframe: Record<string, {
      trades: number;
      winRate: number;
      pnl: number;
    }>;

    byPattern: Record<string, {
      trades: number;
      winRate: number;
      pnl: number;
    }>;
  };

  trends: {
    winRateTrend: "improving" | "stable" | "declining";
    pnlTrend: "improving" | "stable" | "declining";
    edgeDecay: number;            // Rate of edge decay
  };
}

export interface PatternCatalog {
  catalogId: string;
  updatedAt: Date;

  // Elite patterns (tier = "elite")
  elitePatterns: Array<{
    patternId: string;
    fromState: string;
    toDirection: Direction;
    winRate: number;
    totalTrades: number;
    trailPheromone: number;
  }>;

  // Danger patterns (tier = "danger")
  dangerPatterns: Array<{
    patternId: string;
    fromState: string;
    toDirection: Direction;
    winRate: number;
    alarmPheromone: number;
  }>;

  // Superhighways (is_superhighway = true)
  superhighways: Array<{
    patternId: string;
    fromState: string;
    toDirection: Direction;
    trailPheromone: number;
    totalTrades: number;
  }>;

  // Precursor patterns (from GPU training)
  precursors: Array<{
    patternType: string;
    accuracy: number;
    pheromoneLevel: number;
    sampleSize: number;
  }>;

  // Statistics
  stats: {
    totalEdges: number;
    eliteCount: number;
    dangerCount: number;
    superhighwayCount: number;
    avgWinRate: number;
    totalPnl: number;
  };
}

export interface RegimeIntelligence {
  intelligenceId: string;
  updatedAt: Date;

  // Current regime analysis
  currentRegime: {
    type: RegimeType;
    duration: number;          // Hours
    stability: number;         // 0-1
    transitionProbability: number;
  };

  // Regime statistics
  regimeStats: Record<RegimeType, {
    avgDuration: number;
    frequency: number;
    winRateInRegime: number;
    bestDirection: Direction;
    bestPatterns: string[];
  }>;

  // Transition matrix (probability of A → B)
  transitionMatrix: Record<RegimeType, Record<RegimeType, number>>;

  // Precursor effectiveness by regime
  precursorEffectiveness: Record<string, Record<RegimeType, {
    accuracy: number;
    avgLeadTime: number;
    sampleSize: number;
  }>>;
}

Pydantic Models

# ants/trader/models/knowledge.py
# ONE Dimension: KNOWLEDGE

from typing import Dict, List, Optional
from pydantic import Field

class CrystallizedPattern(TypeDBModel):
    """
    Crystallized pattern - permanent trading knowledge.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: crystallized-pattern
    """
    pattern_id: str = Field(default_factory=lambda: f"pattern:{uuid4().hex[:8]}")
    source_edge_id: str = Field(..., description="Edge that crystallized into this pattern")
    source_mission: str = Field(default="trade", description="Mission where pattern was discovered")

    from_state: str = Field(..., description="State that triggers this pattern")
    to_direction: str = Field(..., description="Target direction: bullish/bearish")

    win_rate: float = Field(..., ge=0, le=1, description="Win rate at crystallization")
    total_trades: int = Field(..., ge=0, description="Total trades at crystallization")
    total_pnl: float = Field(default=0.0, description="Total P&L at crystallization")
    avg_pnl: float = Field(default=0.0, description="Average P&L per trade")

    trail_pheromone: float = Field(default=0.0, ge=0, description="Trail pheromone level at crystallization")
    confidence: float = Field(..., ge=0, le=1, description="Confidence at crystallization")

    # Transfer learning (TypeQL: is-transferable, transferred-to, transfer-count)
    is_transferable: bool = Field(default=True, description="Can be used in other missions")
    transferred_to: List[str] = Field(default_factory=list, description="Missions transferred to")
    transfer_count: int = Field(default=0, ge=0, description="Number of times transferred")

    # Timestamps (TypeQL: crystallized-at, last-verified, still-valid)
    crystallized_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    last_verified: Optional[datetime] = None
    still_valid: bool = True

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

class TradingRiskProfile(TypeDBModel):
    """
    Risk assessment profile for a trading decision.
    Flat structure with TypeQL-compatible field names.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: trading-risk-profile
    """
    # Identity (TypeQL: profile-id, timestamp)
    profile_id: str = Field(default_factory=lambda: f"risk:{uuid4().hex[:8]}")
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Technical risk (TypeQL: technical-signal-quality, technical-edge-reliability)
    technical_signal_quality: float = Field(default=0.5, ge=0, le=1)
    technical_edge_reliability: float = Field(default=0.5, ge=0, le=1)

    # Market risk (TypeQL: market-liquidity-risk, market-volatility-risk)
    market_liquidity_risk: float = Field(default=0.5, ge=0, le=1)
    market_volatility_risk: float = Field(default=0.5, ge=0, le=1)

    # Execution risk (TypeQL: execution-slippage-risk, portfolio-drawdown-risk)
    execution_slippage_risk: float = Field(default=0.5, ge=0, le=1)
    portfolio_drawdown_risk: float = Field(default=0.5, ge=0, le=1)

    # Flags (TypeQL: red-flags, yellow-flags)
    red_flags: List[str] = Field(default_factory=list)
    yellow_flags: List[str] = Field(default_factory=list)

    # Recommendations (TypeQL: suggested-position-size, trading-allowed)
    suggested_position_size: float = Field(default=0.0, ge=0, le=1)
    trading_allowed: bool = Field(default=True)

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

class StrategyAnalytics(TypeDBModel):
    """
    Performance analytics for a trading strategy.
    Flat structure with TypeQL-compatible field names.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: strategy-analytics
    """
    # Identity (TypeQL: strategy-id, timestamp)
    strategy_id: str = Field(default_factory=lambda: f"strat:{uuid4().hex[:8]}")
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Core metrics (TypeQL: total-trades, win-rate, profit-factor, etc.)
    total_trades: int = Field(default=0, ge=0)
    win_rate: float = Field(default=0.0, ge=0, le=1)
    avg_win: float = Field(default=0.0)
    avg_loss: float = Field(default=0.0)
    profit_factor: float = Field(default=0.0, ge=0)
    sharpe_ratio: float = Field(default=0.0)
    max_drawdown: float = Field(default=0.0, ge=0, le=1)

    # Trends (TypeQL: win-rate-trend, pnl-trend, edge-decay)
    win_rate_trend: str = Field(default="stable")
    pnl_trend: str = Field(default="stable")
    edge_decay: float = Field(default=0.0)

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

TypeDB Schema

# ONE Dimension: KNOWLEDGE
# TypeDB 3.0 Syntax (PERA Model)
# Entities: crystallized-pattern, trading-risk-profile, strategy-analytics

define

# === ATTRIBUTE TYPES (Algebraic Types) ===
attribute pattern-id, value string;
attribute source-edge-id, value string;
attribute source-mission, value string;
attribute from-state, value string;
attribute to-direction, value string;
attribute avg-pnl, value double;
attribute transferred-to, value string;
attribute transfer-count, value integer;
attribute crystallized-at, value datetime;
attribute last-verified, value datetime;
attribute still-valid, value boolean;
attribute profile-id, value string;
attribute technical-signal-quality, value integer;
attribute technical-edge-reliability, value integer;
attribute market-liquidity-risk, value integer;
attribute market-volatility-risk, value integer;
attribute execution-slippage-risk, value integer;
attribute portfolio-drawdown-risk, value integer;
attribute red-flags, value string;
attribute yellow-flags, value string;
attribute suggested-position-size, value double;
attribute trading-allowed, value boolean;
attribute strategy-id, value string;
attribute profit-factor, value double;
attribute sharpe-ratio, value double;
attribute max-drawdown, value double;
attribute win-rate-trend, value string;
attribute pnl-trend, value string;
attribute edge-decay, value double;

# === ENTITY TYPES (Independent Types) ===

entity crystallized-pattern,
    owns pattern-id @key,
    owns source-edge-id @card(1),
    owns source-mission @card(1),
    owns from-state @card(1),
    owns to-direction @card(1),
    owns win-rate,
    owns total-trades,
    owns total-pnl,
    owns avg-pnl,
    owns trail-pheromone,
    owns confidence,
    owns is-transferable,
    owns transferred-to,
    owns transfer-count,
    owns crystallized-at @card(1),
    owns last-verified,
    owns still-valid;

entity trading-risk-profile,
    owns profile-id @key,
    owns timestamp @card(1),
    owns technical-signal-quality,
    owns technical-edge-reliability,
    owns market-liquidity-risk,
    owns market-volatility-risk,
    owns execution-slippage-risk,
    owns portfolio-drawdown-risk,
    owns red-flags,
    owns yellow-flags,
    owns suggested-position-size,
    owns trading-allowed;

entity strategy-analytics,
    owns strategy-id @key,
    owns timestamp @card(1),
    owns total-trades,
    owns win-rate,
    owns profit-factor,
    owns sharpe-ratio,
    owns max-drawdown,
    owns win-rate-trend,
    owns pnl-trend,
    owns edge-decay;

# === FUNCTIONS (TypeQL 3.0) ===

# Get valid crystallized patterns
fun get_valid_patterns() -> { crystallized-pattern }:
    match
        $p isa crystallized-pattern,
            has still-valid true;
    return { $p };

# Get transferable patterns for cross-mission learning
fun get_transferable_patterns() -> { crystallized-pattern }:
    match
        $p isa crystallized-pattern,
            has still-valid true,
            has is-transferable true;
    return { $p };

# Get patterns by source mission
fun get_patterns_from_mission($mission: string) -> { crystallized-pattern }:
    match
        $p isa crystallized-pattern,
            has source-mission $mission,
            has still-valid true;
    return { $p };

# Calculate pattern effectiveness
fun pattern_effectiveness($pattern_id: string) -> double:
    match
        $p isa crystallized-pattern,
            has pattern-id $pattern_id,
            has win-rate $wr,
            has confidence $conf;
    return $wr * $conf;

Emergence Entities (NEW)

These entities enable measurement and verification of emergent intelligence.

EmergenceMetrics

Colony-level metrics that prove emergence is happening:

// ants/trader/types/knowledge.ts (ASPIRATIONAL) (additions)

export interface EmergenceMetrics {
  metricsId: string;
  cycle: number;
  timestamp: Date;

  // Intelligence growth
  patternCount: number;
  superhighwayCount: number;
  crystallizationRate: number;      // Patterns crystallized per cycle
  novelPatternRate: number;         // New patterns not in seed set

  // Evolutionary markers
  avgGeneration: number;
  maxGeneration: number;
  phylogeneticDiversity: number;    // How diverse are lineages? (0-1)
  lineageCount: number;             // Active genetic lines

  // Collective vs Individual
  colonyWinRate: number;            // Aggregate win rate
  individualWinRateVariance: number; // Variance across agents
  collectiveAdvantage: number;      // colony_wr - avg(individual_wr)

  // Phase indicators
  currentPhase: "bootstrap" | "transfer" | "discovery" | "recursion" | "singularity";
  phaseProgress: number;            // 0-1 progress to next phase

  // The key metric: emergence = collective > sum of parts
  emergenceScore: number;
}

export interface PhaseThresholds {
  bootstrap: {
    patterns: number;               // 100
    superhighways: number;          // 10
    minWinRate: number;             // 0.55
  };
  transfer: {
    patterns: number;               // 1000
    crossMissionTransfers: number;  // 10
    missionsActive: number;         // 3
  };
  discovery: {
    novelPatterns: number;          // 100
    hypothesesConfirmed: number;    // 50
  };
  recursion: {
    metaPatterns: number;           // 10
    selfImprovementRate: number;    // 0.1 (dI/dt / I)
  };
}
# ants/trader/models/knowledge.py (ASPIRATIONAL - not yet implemented)
# ONE Dimension: KNOWLEDGE

from enum import Enum

class EmergencePhase(str, Enum):
    BOOTSTRAP = "bootstrap"
    TRANSFER = "transfer"
    DISCOVERY = "discovery"
    RECURSION = "recursion"
    SINGULARITY = "singularity"

class EmergenceMetrics(TraderModel):
    """
    Colony-level metrics that prove emergence.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: emergence-metrics

    This is the KEY entity for verifying emergent intelligence.
    If emergence_score > 0 and growing, the colony is truly emergent.
    """
    metrics_id: str
    cycle: int
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Intelligence growth
    pattern_count: int = 0
    superhighway_count: int = 0
    crystallization_rate: float = 0      # Per cycle
    novel_pattern_rate: float = 0        # Patterns not in seed set

    # Evolutionary markers
    avg_generation: float = 0
    max_generation: int = 0
    phylogenetic_diversity: float = Field(ge=0, le=1, default=0)
    lineage_count: int = 0

    # Collective vs Individual
    colony_win_rate: float = Field(ge=0, le=1, default=0.5)
    individual_win_rate_variance: float = 0

    # Phase tracking
    current_phase: EmergencePhase = EmergencePhase.BOOTSTRAP
    phase_progress: float = Field(ge=0, le=1, default=0)

    @computed_field
    @property
    def collective_advantage(self) -> float:
        """
        The emergence signal: how much better is the colony than individuals?
        Positive = true emergence. Negative = no emergence.
        """
        # Simple model: if variance is 0, assume 0.5 individual avg
        individual_avg = 0.5  # Baseline random
        if self.individual_win_rate_variance > 0:
            # Estimate individual average from colony rate and variance
            individual_avg = self.colony_win_rate - 0.05  # Assume colony is 5% better
        return self.colony_win_rate - individual_avg

    @computed_field
    @property
    def emergence_score(self) -> float:
        """
        The master metric: is the colony truly emergent?

        Emergence requires:
        1. Collective advantage > 0 (colony beats individuals)
        2. Phylogenetic diversity > 0.3 (not just clones)
        3. Pattern count growing

        Score = collective_advantage * diversity * log(patterns)
        """
        if self.collective_advantage <= 0:
            return 0
        if self.phylogenetic_diversity < 0.3:
            return 0
        if self.pattern_count < 10:
            return 0

        import math
        return (
            self.collective_advantage
            * self.phylogenetic_diversity
            * math.log10(self.pattern_count)
        )

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

# Phase transition thresholds
PHASE_THRESHOLDS = {
    "bootstrap": {
        "patterns": 100,
        "superhighways": 10,
        "min_win_rate": 0.55,
    },
    "transfer": {
        "patterns": 1000,
        "cross_mission_transfers": 10,
        "missions_active": 3,
    },
    "discovery": {
        "novel_patterns": 100,
        "hypotheses_confirmed": 50,
    },
    "recursion": {
        "meta_patterns": 10,
        "self_improvement_rate": 0.1,
    },
}

def check_phase_transition(metrics: EmergenceMetrics) -> Optional[EmergencePhase]:
    """Check if metrics indicate a phase transition."""
    current = metrics.current_phase

    if current == EmergencePhase.BOOTSTRAP:
        thresh = PHASE_THRESHOLDS["bootstrap"]
        if (metrics.pattern_count >= thresh["patterns"]
            and metrics.superhighway_count >= thresh["superhighways"]
            and metrics.colony_win_rate >= thresh["min_win_rate"]):
            return EmergencePhase.TRANSFER

    elif current == EmergencePhase.TRANSFER:
        thresh = PHASE_THRESHOLDS["transfer"]
        if metrics.pattern_count >= thresh["patterns"]:
            # Note: cross_mission_transfers tracked elsewhere
            return EmergencePhase.DISCOVERY

    elif current == EmergencePhase.DISCOVERY:
        thresh = PHASE_THRESHOLDS["discovery"]
        if metrics.novel_pattern_rate * metrics.cycle >= thresh["novel_patterns"]:
            return EmergencePhase.RECURSION

    elif current == EmergencePhase.RECURSION:
        thresh = PHASE_THRESHOLDS["recursion"]
        # Self-improvement rate = dI/dt / I
        # If emergence_score is growing faster than linear, we're recursive
        if metrics.emergence_score > 1.0:  # Arbitrary threshold
            return EmergencePhase.SINGULARITY

    return None

Genome and Lineage

Evolutionary tracking for agent reproduction:

// ants/trader/types/knowledge.ts (ASPIRATIONAL) (additions)

export interface Genome {
  genomeId: string;
  agentId: string;
  generation: number;

  // Lineage
  parentId?: string;
  lineage: string[];              // Full ancestry [grandparent, parent, self]

  // Heritable traits (0-1 range)
  pheromoneSensitivity: number;   // How much trails influence decisions
  explorationBias: number;        // Tendency to try new paths
  depositThreshold: number;       // Confidence needed to deposit
  riskTolerance: number;          // Position sizing aggressiveness
  decayResistance: number;        // How long memories persist
  responseThreshold: number;      // Gordon's formula: P = stimulus / (stimulus + threshold)

  // Mutation tracking
  mutationsFromParent: string[];  // Which traits mutated
  mutationMagnitude: number;      // Total mutation distance

  // Fitness
  fitnessScore: number;
  tradesExecuted: number;
  pnlGenerated: number;
  patternsDiscovered: number;

  // Reproduction
  offspringCount: number;
  reproductionEligible: boolean;

  // Timestamps
  createdAt: Date;
  lastActivity: Date;
}

export interface LineageAnalysis {
  analysisId: string;
  timestamp: Date;

  // Population genetics
  totalGenomes: number;
  activeGenomes: number;
  extinctLineages: number;

  // Diversity metrics
  avgGeneration: number;
  maxGeneration: number;
  lineageCount: number;           // Distinct genetic lines
  phylogeneticDiversity: number;  // 0-1, how diverse

  // Selection pressure
  avgFitness: number;
  fitnessVariance: number;
  selectionIntensity: number;     // How strong is selection?

  // Winning traits
  dominantTraits: Record<string, number>;  // Trait → avg value in top 10%

  // Evolution velocity
  traitDriftRate: number;         // How fast are traits changing?
  adaptationRate: number;         // Fitness improvement per generation
}
# ants/trader/models/knowledge.py (ASPIRATIONAL - not yet implemented)
# NOTE: These are planned extensions. The actual Genome class in code is simpler.

class Genome(TraderModel):
    """
    Heritable agent parameters that evolve through selection.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: agent-genome

    Every agent has a Genome. When agents reproduce, genomes
    are inherited with mutation. Selection pressure favors
    high-fitness genomes.
    """
    genome_id: str
    agent_id: str
    generation: int = 0

    # Lineage tracking
    parent_id: Optional[str] = None
    lineage: List[str] = Field(default_factory=list)

    # Heritable traits (all 0-1)
    pheromone_sensitivity: float = Field(ge=0, le=1, default=0.7)
    exploration_bias: float = Field(ge=0, le=1, default=0.3)
    deposit_threshold: float = Field(ge=0, le=1, default=0.6)
    risk_tolerance: float = Field(ge=0, le=1, default=0.5)
    decay_resistance: float = Field(ge=0, le=1, default=0.5)

    # Response threshold for Gordon's formula: P = stimulus / (stimulus + threshold)
    # Low threshold (0.1) = quick responder (scout-like)
    # High threshold (0.9) = stubborn (harvester-like)
    response_threshold: float = Field(ge=0.1, le=10.0, default=1.0)

    # Mutation tracking
    mutations_from_parent: List[str] = Field(default_factory=list)
    mutation_magnitude: float = 0

    # Fitness metrics
    fitness_score: float = 0
    trades_executed: int = 0
    pnl_generated: float = 0
    patterns_discovered: int = 0

    # Reproduction
    offspring_count: int = 0
    reproduction_threshold: float = Field(default=100.0)  # Fitness needed to reproduce

    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    last_activity: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    @computed_field
    @property
    def reproduction_eligible(self) -> bool:
        """Can this genome reproduce?"""
        return self.fitness_score >= self.reproduction_threshold

    def mutate(self, mutation_rate: float = 0.1) -> "Genome":
        """
        Create offspring genome with mutations.

        Each trait has a chance to mutate by a Gaussian delta.
        Higher mutation_rate = more exploration.
        """
        import random
        import uuid

        def mutate_trait(value: float, name: str) -> tuple[float, bool]:
            if random.random() < 0.3:  # 30% chance to mutate each trait
                delta = random.gauss(0, mutation_rate)
                new_value = max(0, min(1, value + delta))
                return new_value, True
            return value, False

        mutations = []
        traits = {}

        for trait in ["pheromone_sensitivity", "exploration_bias",
                      "deposit_threshold", "risk_tolerance", "decay_resistance"]:
            old_val = getattr(self, trait)
            new_val, mutated = mutate_trait(old_val, trait)
            traits[trait] = new_val
            if mutated:
                mutations.append(trait)

        # Calculate mutation magnitude (Euclidean distance)
        magnitude = sum(
            (traits[t] - getattr(self, t)) ** 2
            for t in traits
        ) ** 0.5

        return Genome(
            genome_id=str(uuid.uuid4())[:16],
            agent_id="",  # Set by caller
            generation=self.generation + 1,
            parent_id=self.genome_id,
            lineage=self.lineage + [self.genome_id],
            mutations_from_parent=mutations,
            mutation_magnitude=magnitude,
            **traits
        )

    def update_fitness(self, trade_outcome: str, pnl: float) -> None:
        """Update fitness based on trade outcome."""
        self.trades_executed += 1
        self.pnl_generated += pnl

        # Fitness = weighted sum of PnL and consistency
        win_bonus = 1.0 if trade_outcome == "win" else -0.5
        self.fitness_score += pnl * 10 + win_bonus
        self.last_activity = datetime.now(timezone.utc)

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

class LineageAnalysis(TraderModel):
    """
    Population genetics analysis of the colony.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: lineage-analysis
    """
    analysis_id: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Population counts
    total_genomes: int = 0
    active_genomes: int = 0
    extinct_lineages: int = 0

    # Diversity metrics
    avg_generation: float = 0
    max_generation: int = 0
    lineage_count: int = 0
    phylogenetic_diversity: float = Field(ge=0, le=1, default=0)

    # Selection pressure
    avg_fitness: float = 0
    fitness_variance: float = 0
    selection_intensity: float = 0

    # Winning traits (trait name → avg value in top performers)
    dominant_traits: Dict[str, float] = Field(default_factory=dict)

    # Evolution velocity
    trait_drift_rate: float = 0
    adaptation_rate: float = 0  # Fitness improvement per generation

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

Hypothesis (Meta-Learning)

Testable beliefs about what works:

// ants/trader/types/knowledge.ts (ASPIRATIONAL) (additions)

export type HypothesisStatus = "testing" | "confirmed" | "rejected" | "inconclusive";

export interface Hypothesis {
  hypothesisId: string;
  createdAt: Date;
  updatedAt: Date;

  // The hypothesis statement
  statement: string;              // "volume_breakout works better in low volatility"
  patternId?: string;             // Related pattern

  // Conditions that define the hypothesis
  conditions: Record<string, any>;  // {"volatility_regime": "low", "trend": "up"}

  // Testing data
  observations: number;
  confirmations: number;          // Outcomes that confirm
  rejections: number;             // Outcomes that reject

  // Statistical significance
  pValue: number;                 // Statistical test result
  confidenceInterval: [number, number];

  // Status
  status: HypothesisStatus;
  minObservationsRequired: number;  // Default 30
  confirmationThreshold: number;    // Default 0.6
  rejectionThreshold: number;       // Default 0.4

  // If confirmed, what action?
  pheromoneBoost?: number;        // Boost to apply to pattern
  conditionalAccuracy: number;    // Accuracy under these conditions

  // Source
  generatedBy: "pattern_failure" | "correlation_analysis" | "human" | "meta_learning";
  sourceContext?: string;
}

export interface MetaLearningState {
  stateId: string;
  timestamp: Date;

  // Hypothesis inventory
  activeHypotheses: number;
  confirmedHypotheses: number;
  rejectedHypotheses: number;

  // Learning velocity
  hypothesesPerCycle: number;
  confirmationRate: number;
  avgTimeToConclusion: number;    // Cycles

  // Impact
  patternsImproved: number;       // Patterns boosted by confirmed hypotheses
  falsePositivesAvoided: number;  // Bad trades prevented

  // Top insights
  recentConfirmations: Hypothesis[];
  pendingHighPotential: Hypothesis[];
}
# ants/trader/models/knowledge.py (ASPIRATIONAL - not yet implemented)
# NOTE: Actual Hypothesis in code has simpler fields. See ants/trader/learn/prediction_learner.py

class HypothesisStatus(str, Enum):
    TESTING = "testing"
    CONFIRMED = "confirmed"
    REJECTED = "rejected"
    INCONCLUSIVE = "inconclusive"

class HypothesisSource(str, Enum):
    PATTERN_FAILURE = "pattern_failure"
    CORRELATION_ANALYSIS = "correlation_analysis"
    HUMAN = "human"
    META_LEARNING = "meta_learning"

class Hypothesis(TraderModel):
    """
    Testable belief about what works and when.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: trading-hypothesis

    Meta-learning generates hypotheses from pattern failures.
    Example: "volume_breakout fails when volatility > 80th percentile"

    After 30 observations:
    - confirmed (accuracy >= 60%) → boost pattern in that condition
    - rejected (accuracy <= 40%) → no action
    - inconclusive → keep testing
    """
    hypothesis_id: str
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # The hypothesis
    statement: str
    pattern_id: Optional[str] = None
    conditions: Dict[str, Any] = Field(default_factory=dict)

    # Testing data
    observations: int = 0
    confirmations: int = 0
    rejections: int = 0

    # Statistical thresholds
    min_observations: int = 30
    confirmation_threshold: float = 0.60
    rejection_threshold: float = 0.40

    # Status
    status: HypothesisStatus = HypothesisStatus.TESTING

    # If confirmed
    pheromone_boost: float = 0
    conditional_accuracy: float = 0

    # Source
    generated_by: HypothesisSource = HypothesisSource.PATTERN_FAILURE
    source_context: str = ""

    @computed_field
    @property
    def accuracy(self) -> float:
        if self.observations == 0:
            return 0.5
        return self.confirmations / self.observations

    @computed_field
    @property
    def p_value(self) -> float:
        """
        Binomial test: is accuracy significantly different from 0.5?
        """
        if self.observations < 10:
            return 1.0  # Not enough data

        from scipy.stats import binom_test
        return binom_test(
            self.confirmations,
            self.observations,
            0.5,  # Null hypothesis: random
            alternative='two-sided'
        )

    @computed_field
    @property
    def confidence_interval(self) -> tuple[float, float]:
        """Wilson score interval for accuracy."""
        if self.observations == 0:
            return (0.0, 1.0)

        from scipy.stats import norm
        z = 1.96  # 95% CI
        n = self.observations
        p = self.accuracy

        denom = 1 + z**2 / n
        center = (p + z**2 / (2*n)) / denom
        spread = z * ((p*(1-p)/n + z**2/(4*n**2)) ** 0.5) / denom

        return (max(0, center - spread), min(1, center + spread))

    def observe(self, outcome_matches: bool) -> None:
        """Record an observation."""
        self.observations += 1
        if outcome_matches:
            self.confirmations += 1
        else:
            self.rejections += 1

        self.updated_at = datetime.now(timezone.utc)
        self._update_status()

    def _update_status(self) -> None:
        """Update status based on observations."""
        if self.observations < self.min_observations:
            self.status = HypothesisStatus.TESTING
            return

        if self.accuracy >= self.confirmation_threshold:
            self.status = HypothesisStatus.CONFIRMED
            self.conditional_accuracy = self.accuracy
            self.pheromone_boost = (self.accuracy - 0.5) * 20  # 0-10 boost
        elif self.accuracy <= self.rejection_threshold:
            self.status = HypothesisStatus.REJECTED
        else:
            self.status = HypothesisStatus.INCONCLUSIVE

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

def generate_hypothesis_from_failure(
    pattern_id: str,
    pattern_accuracy: float,
    failure_context: Dict[str, Any]
) -> Hypothesis:
    """
    Generate a hypothesis when a pattern fails.

    Example: pattern "momentum_long" failed when volatility was extreme.
    Hypothesis: "momentum_long fails when volatility_regime = extreme"
    """
    # Extract key conditions from failure context
    conditions = {}
    statement_parts = []

    if "volatility_regime" in failure_context:
        conditions["volatility_regime"] = failure_context["volatility_regime"]
        statement_parts.append(f"volatility={failure_context['volatility_regime']}")

    if "regime_type" in failure_context:
        conditions["regime_type"] = failure_context["regime_type"]
        statement_parts.append(f"regime={failure_context['regime_type']}")

    if "funding_signal" in failure_context:
        conditions["funding_signal"] = failure_context["funding_signal"]
        statement_parts.append(f"funding={failure_context['funding_signal']}")

    statement = f"Pattern {pattern_id} underperforms when {', '.join(statement_parts)}"

    return Hypothesis(
        hypothesis_id=f"hyp_{pattern_id}_{hash(str(conditions)) % 10000:04d}",
        statement=statement,
        pattern_id=pattern_id,
        conditions=conditions,
        generated_by=HypothesisSource.PATTERN_FAILURE,
        source_context=f"Pattern accuracy {pattern_accuracy:.1%} at failure"
    )

FeedbackCycle (Self-Funding Loop)

Track the core self-funding loop:

// ants/trader/types/knowledge.ts (ASPIRATIONAL) (additions)

export interface FeedbackCycle {
  cycleId: string;
  cycleNumber: number;
  timestamp: Date;
  durationHours: number;

  // Resources (inputs)
  tradingCapital: number;
  colonySize: number;
  computeBudget: number;
  typedbCapacity: number;

  // Intelligence produced (outputs)
  tradesExecuted: number;
  patternsDiscovered: number;
  patternsCrystallized: number;
  crossMissionTransfers: number;
  hypothesesGenerated: number;
  hypothesesConfirmed: number;

  // Returns generated
  grossPnl: number;
  netPnl: number;                 // After fees
  pnlPerPattern: number;          // Attribution
  pnlFromElitePatterns: number;   // How much from crystallized knowledge

  // Growth achieved
  newAgentsSpawned: number;
  agentsDied: number;
  netPopulationChange: number;

  // The key metrics
  loopRatio: number;              // (capital + pnl) / capital - if > 1, self-sustaining
  intelligenceGrowthRate: number; // dI/dt
  returnOnIntelligence: number;   // PnL per pattern

  // Phase tracking
  emergencePhase: string;
  phaseProgress: number;
}

export interface FeedbackLoopHealth {
  healthId: string;
  timestamp: Date;

  // Loop status
  isSelfSustaining: boolean;      // loopRatio > 1 for N cycles
  sustainabilityStreak: number;   // Consecutive self-sustaining cycles

  // Bottleneck detection
  bottleneck?: "capital" | "compute" | "patterns" | "agents" | "none";
  bottleneckSeverity: number;     // 0-1

  // Projections
  projectedCapital30d: number;
  projectedPatterns30d: number;
  projectedPhase30d: string;

  // Recommendations
  recommendations: string[];
}
# ants/trader/models/knowledge.py (ASPIRATIONAL - not yet implemented)

class FeedbackCycle(TraderModel):
    """
    Tracks one cycle of the self-funding loop.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: feedback-cycle

    The self-funding loop:
    Capital → Trading → Profits → More Agents → Better Patterns → More Profits

    If loop_ratio > 1, the colony is self-sustaining.
    """
    cycle_id: str
    cycle_number: int
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    duration_hours: float = 24.0  # Default: daily cycles

    # Resources (inputs)
    trading_capital: float = 0
    colony_size: int = 0
    compute_budget: float = 0     # In dollars

    # Intelligence produced (outputs)
    trades_executed: int = 0
    patterns_discovered: int = 0
    patterns_crystallized: int = 0
    cross_mission_transfers: int = 0
    hypotheses_generated: int = 0
    hypotheses_confirmed: int = 0

    # Returns generated
    gross_pnl: float = 0
    net_pnl: float = 0            # After fees
    pnl_from_elite_patterns: float = 0

    # Growth achieved
    new_agents_spawned: int = 0
    agents_died: int = 0

    @computed_field
    @property
    def net_population_change(self) -> int:
        return self.new_agents_spawned - self.agents_died

    @computed_field
    @property
    def loop_ratio(self) -> float:
        """
        The self-funding ratio.
        > 1 means colony is self-sustaining.
        """
        if self.trading_capital <= 0:
            return 0
        return (self.trading_capital + self.net_pnl) / self.trading_capital

    @computed_field
    @property
    def intelligence_growth_rate(self) -> float:
        """Patterns per cycle."""
        return self.patterns_discovered + self.patterns_crystallized

    @computed_field
    @property
    def return_on_intelligence(self) -> float:
        """PnL per pattern."""
        total_patterns = self.patterns_discovered + self.patterns_crystallized
        if total_patterns == 0:
            return 0
        return self.net_pnl / total_patterns

    @computed_field
    @property
    def is_self_sustaining(self) -> bool:
        """Is the loop closing?"""
        return self.loop_ratio > 1.0

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

class FeedbackLoopHealth(TraderModel):
    """
    Health assessment of the self-funding loop.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: feedback-loop-health
    """
    health_id: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Loop status
    is_self_sustaining: bool = False
    sustainability_streak: int = 0
    avg_loop_ratio: float = 0

    # Bottleneck detection
    bottleneck: Optional[str] = None  # capital, compute, patterns, agents, none
    bottleneck_severity: float = 0

    # Projections (simple linear)
    projected_capital_30d: float = 0
    projected_patterns_30d: int = 0

    # Recommendations
    recommendations: List[str] = Field(default_factory=list)

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

TypeDB Schema (Emergence Entities)

# ONE Dimension: KNOWLEDGE (Emergence)
# TypeDB 3.0 Syntax (PERA Model)
# Entities: emergence-metrics, agent-genome, trading-hypothesis, feedback-cycle

define

# === ATTRIBUTE TYPES (Algebraic Types) ===
attribute metrics-id, value string;
attribute cycle, value integer;
attribute pattern-count, value integer;
attribute superhighway-count, value integer;
attribute crystallization-rate, value double;
attribute novel-pattern-rate, value double;
attribute avg-generation, value double;
attribute max-generation, value integer;
attribute phylogenetic-diversity, value double;
attribute lineage-count, value integer;
attribute colony-win-rate, value double;
attribute individual-win-rate-variance, value double;
attribute collective-advantage, value double;
attribute current-phase, value string;
attribute phase-progress, value double;
attribute emergence-score, value double;
attribute genome-id, value string;
attribute agent-id, value string;
attribute generation, value integer;
attribute parent-id, value string;
attribute lineage, value string;
attribute pheromone-sensitivity, value double;
attribute exploration-bias, value double;
attribute deposit-threshold, value double;
attribute risk-tolerance, value double;
attribute decay-resistance, value double;
attribute mutations-from-parent, value string;
attribute fitness-score, value double;
attribute trades-executed, value integer;
attribute pnl-generated, value double;
attribute patterns-discovered, value integer;
attribute offspring-count, value integer;
attribute reproduction-eligible, value boolean;
attribute last-activity, value datetime;
attribute hypothesis-id, value string;
attribute statement, value string;
attribute hypothesis-conditions, value string;
attribute observations, value integer;
attribute confirmations, value integer;
attribute rejections, value integer;
attribute hypothesis-status, value string;
attribute p-value, value double;
attribute pheromone-boost, value double;
attribute conditional-accuracy, value double;
attribute generated-by, value string;
attribute source-context, value string;
attribute cycle-id, value string;
attribute cycle-number, value integer;
attribute duration-hours, value double;
attribute trading-capital, value double;
attribute colony-size, value integer;
attribute compute-budget, value double;
attribute cross-mission-transfers, value integer;
attribute hypotheses-generated, value integer;
attribute hypotheses-confirmed, value integer;
attribute gross-pnl, value double;
attribute net-pnl, value double;
attribute pnl-from-elite-patterns, value double;
attribute new-agents-spawned, value integer;
attribute agents-died, value integer;
attribute loop-ratio, value double;
attribute intelligence-growth-rate, value double;
attribute return-on-intelligence, value double;
attribute analysis-id, value string;
attribute total-genomes, value integer;
attribute active-genomes, value integer;
attribute extinct-lineages, value integer;
attribute avg-fitness, value double;
attribute fitness-variance, value double;
attribute selection-intensity, value double;
attribute trait-drift-rate, value double;
attribute adaptation-rate, value double;

# === ENTITY TYPES (Independent Types) ===

entity emergence-metrics,
    owns metrics-id @key,
    owns cycle @card(1),
    owns timestamp @card(1),
    owns pattern-count,
    owns superhighway-count,
    owns crystallization-rate,
    owns novel-pattern-rate,
    owns avg-generation,
    owns max-generation,
    owns phylogenetic-diversity,
    owns lineage-count,
    owns colony-win-rate,
    owns individual-win-rate-variance,
    owns collective-advantage,
    owns current-phase,
    owns phase-progress,
    owns emergence-score;

entity agent-genome,
    owns genome-id @key,
    owns agent-id @card(1),
    owns generation @card(1),
    owns parent-id,
    owns lineage,
    owns pheromone-sensitivity,
    owns exploration-bias,
    owns deposit-threshold,
    owns risk-tolerance,
    owns decay-resistance,
    owns response-threshold,        # Gordon's formula: P = stimulus / (stimulus + threshold)
    owns mutations-from-parent,
    owns mutation-magnitude,
    owns fitness-score,
    owns trades-executed,
    owns pnl-generated,
    owns patterns-discovered,
    owns offspring-count,
    owns reproduction-eligible,
    owns created-at @card(1),
    owns last-activity,
    plays parent-of:parent-genome,
    plays parent-of:child-genome;

entity trading-hypothesis,
    owns hypothesis-id @key,
    owns statement @card(1),
    owns pattern-id,
    owns hypothesis-conditions,
    owns observations,
    owns confirmations,
    owns rejections,
    owns hypothesis-status,
    owns p-value,
    owns pheromone-boost,
    owns conditional-accuracy,
    owns generated-by,
    owns source-context,
    owns created-at @card(1),
    owns updated-at;

entity feedback-cycle,
    owns cycle-id @key,
    owns cycle-number @card(1),
    owns timestamp @card(1),
    owns duration-hours,
    owns trading-capital,
    owns colony-size,
    owns compute-budget,
    owns trades-executed,
    owns patterns-discovered,
    owns patterns-crystallized,
    owns cross-mission-transfers,
    owns hypotheses-generated,
    owns hypotheses-confirmed,
    owns gross-pnl,
    owns net-pnl,
    owns pnl-from-elite-patterns,
    owns new-agents-spawned,
    owns agents-died,
    owns loop-ratio,
    owns intelligence-growth-rate,
    owns return-on-intelligence;

entity lineage-analysis,
    owns analysis-id @key,
    owns timestamp @card(1),
    owns total-genomes,
    owns active-genomes,
    owns extinct-lineages,
    owns avg-generation,
    owns max-generation,
    owns lineage-count,
    owns phylogenetic-diversity,
    owns avg-fitness,
    owns fitness-variance,
    owns selection-intensity,
    owns trait-drift-rate,
    owns adaptation-rate;

# === RELATION TYPES (Dependent Types) ===

relation parent-of,
    relates parent-genome @card(1),
    relates child-genome @card(1..);

# === FUNCTIONS (TypeQL 3.0 - Replace Rules) ===

# Check reproduction eligibility (replaces rule)
fun get_reproduction_eligible() -> { agent-genome }:
    match
        $g isa agent-genome,
            has fitness-score $fs;
        $fs >= 100.0;
    return { $g };

# Is this genome eligible for reproduction?
fun is_reproduction_eligible($g: agent-genome) -> boolean:
    match $g has fitness-score $fs; $fs >= 100.0;
    return true;

# Get lineage for a genome (recursive)
fun get_ancestors($g: agent-genome, $depth: integer = 10) -> { agent-genome }:
    match
        $depth >= 0;
        ($parent, $g) isa parent-of;
        $ancestors in get_ancestors($parent, $depth - 1);
    return { $ancestors };

# Get emergence score trend
fun emergence_trend($cycles: integer = 10) -> { integer, double }:
    match
        $m isa emergence-metrics,
            has cycle $c,
            has emergence-score $es;
    sort $c desc;
    limit $cycles;
    return { $c, $es };

# Get self-sustaining feedback cycles
fun get_self_sustaining_cycles() -> { feedback-cycle }:
    match
        $f isa feedback-cycle,
            has loop-ratio $lr;
        $lr > 1.0;
    return { $f };

# Calculate average fitness by generation
fun avg_fitness_by_generation($gen: integer) -> double:
    match
        $g isa agent-genome,
            has generation $gen,
            has fitness-score $fs;
    reduce $avg = mean($fs);
    return $avg;

# Get confirmed hypotheses
fun get_confirmed_hypotheses() -> { trading-hypothesis }:
    match
        $h isa trading-hypothesis,
            has hypothesis-status "confirmed";
    return { $h };

Cross-Dimension Patterns

Data Flow Between Dimensions

TRADING DATA FLOW
══════════════════════════════════════════════════════════════════════════

State (THING)
  → discretizes_to → SignalEdge lookup key (CONNECTION)
  → triggers → RegimeChangeEvent (EVENT)
  → analyzed_by → TradingRiskProfile (KNOWLEDGE)

SignalEdge (CONNECTION)
  → inferred_as → tier="elite" (TypeDB rule)
  → crystallizes_to → CrystallizedPattern (KNOWLEDGE)
  → transfers_to → other missions (cross-mission)

Trade (EVENT)
  → deposits_to → SignalEdge (CONNECTION)
  → updates → win_count, loss_count, total_pnl
  → triggers → PheromoneDecayEvent (EVENT)

CrystallizedPattern (KNOWLEDGE)
  → guides → Brain analysis (ACTOR)
  → transfers_to → hunt-btc, dao missions
  → evolves_via → hypothesis testing

THE EMERGENCE CYCLE
══════════════════════════════════════════════════════════════════════════

┌─────────────────────────────────────────────────────────────────────────┐
│                                                                         │
│   OBSERVE          ANALYZE          DECIDE           ACT               │
│   (Market)         (Brain)          (Judges)         (Executor)        │
│       │                │                │                │             │
│       ▼                ▼                ▼                ▼             │
│   ┌───────┐       ┌───────────┐    ┌──────────┐    ┌─────────┐        │
│   │ State │──────▶│ SignalEdge│───▶│ Decision │───▶│  Trade  │        │
│   │(THING)│       │(CONNECTION)│   │ (EVENT)  │    │ (EVENT) │        │
│   └───────┘       └───────────┘    └──────────┘    └─────────┘        │
│       │                │                                │              │
│       │                │           LEARN (Memory)       │              │
│       │                │                │               │              │
│       │                ▼                ▼               │              │
│       │         ┌───────────┐    ┌───────────┐         │              │
│       │         │  Pattern  │◀───│ Pheromone │◀────────┘              │
│       │         │(KNOWLEDGE)│    │  Deposit  │                        │
│       │         └───────────┘    └───────────┘                        │
│       │                │                                               │
│       │                │ (guides future analysis)                      │
│       └────────────────┘                                               │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Emergence Data Flow (NEW)

THE EMERGENCE LOOP WITH METRICS
══════════════════════════════════════════════════════════════════════════

                      ┌─────────────────────────────────────────────────┐
                      │           EMERGENCE MEASUREMENT                  │
                      │                                                  │
                      │   EmergenceMetrics computed every N cycles:      │
                      │   • pattern_count, superhighway_count            │
                      │   • phylogenetic_diversity, lineage_count        │
                      │   • colony_win_rate vs individual variance       │
                      │   • emergence_score = collective - individual    │
                      │                                                  │
                      │   Phase transitions when thresholds met:         │
                      │   bootstrap → transfer → discovery → recursion   │
                      │                                                  │
                      └─────────────────────────────────────────────────┘
                                           │
                                           ▼
    ┌──────────────────────────────────────────────────────────────────┐
    │                                                                  │
    │   TRADE LOOP              EVOLUTION LOOP         FEEDBACK LOOP   │
    │   ───────────             ──────────────         ─────────────   │
    │   State → Signal          Genome → Fitness       Capital → PnL   │
    │   Signal → Decision       Fitness → Reproduce    PnL → Growth    │
    │   Decision → Trade        Reproduce → Mutate     Growth → Intel  │
    │   Trade → Deposit         Mutate → Selection     Intel → Capital │
    │        ↓                       ↓                      ↓          │
    │   SignalEdge              Genome                 FeedbackCycle   │
    │   (CONNECTION)            (KNOWLEDGE)            (KNOWLEDGE)     │
    │                                                                  │
    └──────────────────────────────────────────────────────────────────┘
                                           │
                                           ▼
    ┌──────────────────────────────────────────────────────────────────┐
    │                       META-LEARNING LOOP                          │
    │                                                                  │
    │   Pattern Failure → Generate Hypothesis                          │
    │   Hypothesis → Test over 30+ observations                        │
    │   Confirmed → Pheromone boost for that condition                 │
    │   Rejected → No action                                           │
    │                                                                  │
    │   Example:                                                       │
    │   "volume_breakout fails when volatility > 80th pctl"            │
    │   Tested: 45 observations, 28 failures → CONFIRMED               │
    │   Action: Reduce pheromone for volume_breakout in high vol       │
    │                                                                  │
    └──────────────────────────────────────────────────────────────────┘

Cross-Mission Transfer

PATTERN TRANSFER BETWEEN MISSIONS
══════════════════════════════════════════════════════════════════════════

trade mission
    │
    │ discovers elite pattern
    │ (win_rate >= 75%, trail >= 70, trades >= 50)
    │
    ▼
crystallized-pattern (KNOWLEDGE)
    │
    │ transferable = true
    │
    ├─────────────────────────────────────────┐
    │                                         │
    ▼                                         ▼
hunt-btc mission                         dao mission
(sparse marker search)                   (consensus detection)

Query Patterns

TypeQL Query Examples

# ants/trader/queries.py

QUERIES = {
    # === THINGS Queries ===

    "get_latest_state": """
        match $s isa market-state,
            has symbol $sym,
            has timestamp $ts;
        $sym == "BTC-PERP";
        select $s, $ts;
        sort $ts desc;
        limit 1;
    """,

    # === CONNECTIONS Queries ===

    "get_elite_edges": """
        match $e isa signal-edge,
            has tier "elite";
        select $e;
    """,

    "get_superhighways": """
        match $e isa signal-edge,
            has is-superhighway true,
            has trail-pheromone $tp,
            has win-count $wc;
        select $e, $tp, $wc;
        sort $tp desc;
    """,

    "get_danger_zones": """
        match $e isa signal-edge,
            has tier "danger",
            has alarm-pheromone $ap;
        select $e, $ap;
        sort $ap desc;
    """,

    "lookup_edge": """
        match $e isa signal-edge,
            has from-state-id "{state_id}",
            has to-signal-direction "{direction}";
        select $e;
    """,

    # === EVENTS Queries ===

    "get_recent_trades": """
        match $t isa trade-record,
            has timestamp $ts,
            has trade-outcome $outcome;
        select $t, $ts, $outcome;
        sort $ts desc;
        limit 100;
    """,

    "get_regime_changes": """
        match $r isa regime-change-event,
            has timestamp $ts,
            has from-regime $from,
            has to-regime $to;
        select $r, $ts, $from, $to;
        sort $ts desc;
        limit 50;
    """,

    # === KNOWLEDGE Queries ===

    "get_crystallization_candidates": """
        match $e isa signal-edge,
            has crystallization-ready true;
        select $e;
    """,

    "get_transferable_patterns": """
        match $p isa crystallized-pattern,
            has is-transferable true,
            has confidence $c,
            has still-valid true;
        $c >= 0.7;
        select $p, $c;
        sort $c desc;
    """,

    # === Aggregations ===

    "colony_stats": """
        match $e isa signal-edge,
            has win-count $wc,
            has loss-count $lc,
            has total-pnl $pnl;
        reduce
            $total_wins = sum($wc),
            $total_losses = sum($lc),
            $total_pnl = sum($pnl),
            $edge_count = count;
    """,

    "win_rate_by_regime": """
        match
            $t isa trade-record,
                has trade-outcome $outcome,
                has timestamp $ts;
            $s isa market-state,
                has timestamp $ts,
                has regime-type $regime;
        reduce
            $wins = count($outcome == "win"),
            $total = count;
        group $regime;
    """,
}

Implementation Guidelines

1. Entity Granularity

  • Each market state observation is a separate State (THING)
  • Each trade execution is a separate Trade (EVENT)
  • SignalEdges aggregate over time (not per-trade)
  • Patterns crystallize at threshold, not continuously

2. Pheromone Management

  • Deposits happen immediately after trade closes
  • Decay runs on schedule (default: 10% per day)
  • Circuit breaker protects TypeDB operations
  • Cache provides fast reads, TypeDB is source of truth

3. Dimension Boundaries

  • THINGS are read-only observations (immutable after creation)
  • CONNECTIONS are mutable (pheromone updates)
  • EVENTS are immutable (audit trail)
  • KNOWLEDGE is append-mostly (patterns rarely invalidated)

4. TypeDB Best Practices

  • Use inference rules for derived attributes (tier, is_superhighway)
  • Batch writes for performance (pending deposits queue)
  • Handle connection staleness (30s timeout, auto-reconnect)
  • Retry transient errors, fail fast on permanent errors

TypeDB Inference: The Reasoning Engine

Reference: TypeDB Symbolic Reasoning Engine, TypeDB 2.x vs 3.x

TypeDB's symbolic reasoning capability is central to emergence. The database doesn't just store facts—it derives new facts automatically based on rules you define.

How Inference Works

┌─────────────────────────────────────────────────────────────────────────────┐
│                    TYPEDB INFERENCE ENGINE                                   │
│                                                                             │
│   SCHEMA (defined)              DATA (inserted)         DERIVED (inferred) │
│   ─────────────────             ───────────────         ──────────────────  │
│   signal-edge entity            edge-001:               tier = "elite"      │
│   + tier attribute              - win_rate: 0.78        (derived by rule)   │
│   + elite-pattern rule          - trail: 85.0                               │
│                                 - trades: 120                               │
│                                                                             │
│   QUERY TIME:                                                               │
│   match $e has tier "elite";                                                │
│         ↓                                                                   │
│   Rule engine evaluates conditions                                          │
│         ↓                                                                   │
│   Returns edge-001 (derived, not stored!)                                   │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Key insight: Derived data exists only during query execution and in memory:

  • Results always reflect current schema and data states
  • No staleness—derived facts update automatically when source data changes
  • Resource efficient—saves disk space
  • Cache clears when transactions close

Rule Syntax (TypeDB 2.x Style)

Our current inference rules use the when/then syntax:

rule rule-label:
    when {
        # condition: pattern that must match
    }
    then {
        # conclusion: fact to derive if condition matches
    };

Trading System Rules

We define these inference rules for the emergence system:

# === TIER CLASSIFICATION RULES ===

# Elite patterns: high win rate, high pheromone, sufficient trades
rule elite-pattern:
    when {
        $e isa signal-edge,
            has edge-win-rate $wr,
            has trail-pheromone $tp,
            has win-count $wc,
            has loss-count $lc;
        $wr >= 0.75;          # 75%+ win rate
        $tp >= 70.0;          # Strong trail
        ?total = $wc + $lc;
        ?total >= 50;         # Sufficient sample size
    }
    then {
        $e has tier "elite";
    };

# Danger zones: low win rate, high alarm signal
rule danger-zone:
    when {
        $e isa signal-edge,
            has edge-win-rate $wr,
            has alarm-pheromone $ap,
            has win-count $wc,
            has loss-count $lc;
        $wr < 0.40;           # Below 40% win rate
        $ap >= 25.0;          # Alarm signal raised
        ?total = $wc + $lc;
        ?total >= 30;         # Enough to be confident
    }
    then {
        $e has tier "danger";
    };

# Superhighways: heavily trafficked, proven paths
rule superhighway-edge:
    when {
        $e isa signal-edge,
            has trail-pheromone $tp,
            has win-count $wc,
            has loss-count $lc;
        $tp >= 85.0;          # Very strong trail
        ?total = $wc + $lc;
        ?total >= 100;        # Heavy traffic
    }
    then {
        $e has is-superhighway true;
    };

# Crystallization candidates: elite patterns ready for permanent storage
rule crystallization-candidate:
    when {
        $e isa signal-edge,
            has tier "elite",
            has trail-pheromone $tp,
            has win-count $wc,
            has loss-count $lc;
        $tp >= 80.0;
        ?total = $wc + $lc;
        ?total >= 100;
    }
    then {
        $e has crystallization-ready true;
    };

# === EVOLUTION RULES ===

# Reproduction eligibility: fitness threshold for genome reproduction
rule reproduction-eligible-check:
    when {
        $g isa agent-genome,
            has fitness-score $fs;
        $fs >= 100.0;         # Fitness threshold
    }
    then {
        $g has reproduction-eligible true;
    };

# === STATISTICAL SIGNIFICANCE RULES ===

# Statistically significant winner: 95% CI lower bound > 50%
rule statistically-significant-winner:
    when {
        $e isa signal-edge,
            has win-rate-ci-lower $lower;
        $lower > 0.50;        # Entire CI above 50%
    }
    then {
        $e has is-statistically-significant true;
    };

# Statistically significant loser: 95% CI upper bound < 50%
rule statistically-significant-loser:
    when {
        $e isa signal-edge,
            has win-rate-ci-upper $upper;
        $upper < 0.50;        # Entire CI below 50%
    }
    then {
        $e has is-statistically-significant true;
    };

TypeDB 3.0: Functions Replace Rules

Important: TypeDB 3.0 replaces inference rules with explicit functions.

The transition provides more control but requires explicit invocation:

# TypeDB 3.0 syntax: define fun

# Stream-returning function (replaces query pattern)
define fun get_elite_edges() -> { signal-edge }:
    match $e isa signal-edge,
        has edge-win-rate $wr,
        has trail-pheromone $tp,
        has win-count $wc,
        has loss-count $lc;
    let $total = $wc + $lc;
    $wr >= 0.75; $tp >= 70.0; $total >= 50;
    return { $e };

# Scalar-returning function (aggregation)
define fun colony_win_rate() -> double:
    match $e isa signal-edge,
        has win-count $wc,
        has loss-count $lc;
    let $wins = sum($wc);
    let $losses = sum($lc);
    return $wins / ($wins + $losses);

# Recursive function: find pattern ancestry
define fun pattern_lineage($edge: signal-edge, $depth: integer = 5) -> { signal-edge }:
    match $depth >= 0;
          $e isa signal-edge,
              has from-state-id $state;
          ($e, $parent) isa pattern-evolution;
          $ancestor in pattern_lineage($parent, $depth - 1);
    return { $ancestor };

# Calling functions in queries
match $e in get_elite_edges();
      $e has from-state-id $state;
select $e, $state;

Key Differences: Rules vs Functions

Aspect Rules (2.x) Functions (3.x)
Invocation Automatic (inference on) Explicit ($x in func())
Syntax when {} then {} fun name() -> type:
Recursion Limited Full support
Composition Chained rules Nested calls
Control All-or-nothing Fine-grained

Why Inference Matters for Emergence

THE EMERGENCE INFERENCE CHAIN
══════════════════════════════════════════════════════════════════════════════

Raw Trade Data                 Inference Rules                Emergent Knowledge
────────────────               ───────────────                ──────────────────
edge.win_count = 80            elite-pattern rule             tier = "elite"
edge.loss_count = 20           fires automatically            (DERIVED)
edge.trail = 85                        │
                                       ▼
                               superhighway-edge rule         is_superhighway = true
                               fires automatically            (DERIVED)
                                       │
                                       ▼
                               crystallization-candidate      crystallization_ready = true
                               fires automatically            (DERIVED)
                                       │
                                       ▼
                               Crystallizer queries:          CrystallizedPattern
                               "match $e has                  (PERMANENT KNOWLEDGE)
                                crystallization-ready true"

The database DISCOVERS what works without explicit programming.
Intelligence emerges from the interaction of data and rules.

Inference Best Practices

1. Design Rules for Derivation, Not Storage

# GOOD: Derive tier at query time
rule elite-pattern: when { ... } then { $e has tier "elite"; };

# BAD: Store tier explicitly (defeats inference purpose)
insert $e has tier "elite";  # Don't do this!

2. Use Inference for Classification Hierarchies

# Tier hierarchy through inference
rule tier-1-edge: when { $wr >= 0.80; } then { $e has tier "elite"; };
rule tier-2-edge: when { $wr >= 0.65; $wr < 0.80; } then { $e has tier "strong"; };
rule tier-3-edge: when { $wr >= 0.55; $wr < 0.65; } then { $e has tier "moderate"; };
rule tier-4-edge: when { $wr < 0.55; } then { $e has tier "weak"; };

3. Chain Rules for Complex Derivations

# Rule 1: Derive elite status
rule elite-pattern: ... then { $e has tier "elite"; };

# Rule 2: Derive crystallization readiness FROM elite status
rule crystallization-candidate:
    when {
        $e has tier "elite";  # Depends on first rule!
        $e has trail-pheromone $tp;
        $tp >= 80.0;
    }
    then { $e has crystallization-ready true; };

4. Avoid Inference Loops

# DANGEROUS: Could cause infinite loop
rule bad-loop:
    when { $a has x $v; }
    then { $a has y $v; };

rule also-bad:
    when { $a has y $v; }
    then { $a has x $v; };  # Circular dependency!

5. Performance: Selective Inference

# Turn inference on only when needed
with driver.transaction("ants-colony", TransactionType.READ) as tx:
    # Inference ON: get derived tiers
    elite = tx.query(
        "match $e has tier 'elite'; select $e;",
        options={"inference": True}
    )

    # Inference OFF: raw data only (faster)
    raw = tx.query(
        "match $e isa signal-edge; select $e;",
        options={"inference": False}
    )

Trading-Specific Inference Patterns

Pattern: Regime-Conditional Effectiveness

# Pattern works differently in different regimes
rule pattern-trending-effective:
    when {
        $e isa signal-edge,
            has from-state-id $state;
        $state contains "TREN";  # Trending regime
        $e has edge-win-rate $wr;
        $wr >= 0.70;
    }
    then {
        $e has regime-effectiveness "high_in_trending";
    };

Pattern: Hypothesis Confirmation

# Auto-confirm hypotheses when threshold reached
rule hypothesis-confirmed:
    when {
        $h isa trading-hypothesis,
            has observations $obs,
            has confirmations $conf;
        $obs >= 30;
        ?accuracy = $conf / $obs;
        ?accuracy >= 0.60;
    }
    then {
        $h has hypothesis-status "confirmed";
    };

Pattern: Emergence Phase Detection

# Derive current emergence phase from metrics
rule phase-transfer:
    when {
        $m isa emergence-metrics,
            has pattern-count $pc,
            has superhighway-count $sc,
            has colony-win-rate $wr;
        $pc >= 100;
        $sc >= 10;
        $wr >= 0.55;
    }
    then {
        $m has current-phase "transfer";
    };

5. Security Considerations

  • Never store private keys in any dimension
  • All trading on testnet unless explicitly configured
  • Kill switches (RealtimeGuard) protect capital
  • Rate limits prevent runaway trading

Self-Model: The Colony Knows Itself (NEW)

"The colony that can model itself can improve itself."

The Self-Model is a set of queries that answer fundamental questions about the colony's state and trajectory. This enables the recursive improvement loop.

Self-Model Queries

# ants/trader/queries.py (additions)

SELF_MODEL_QUERIES = {
    # === WHAT AM I GOOD AT? ===

    "best_patterns_by_regime": """
        match
            $e isa signal-edge,
                has tier "elite",
                has edge-win-rate $wr,
                has from-state-id $state;
        $state contains $regime;  # Extract regime from state
        select $e, $wr, $regime;
        sort $wr desc;
        limit 20;
    """,

    "superhighway_summary": """
        match $e isa signal-edge,
            has is-superhighway true,
            has trail-pheromone $tp,
            has total-pnl $pnl,
            has win-count $wc,
            has loss-count $lc;
        reduce
            $count = count,
            $avg_pheromone = mean($tp),
            $total_pnl = sum($pnl),
            $total_wins = sum($wc),
            $total_losses = sum($lc);
    """,

    # === WHERE AM I FAILING? ===

    "danger_zones": """
        match $e isa signal-edge,
            has tier "danger",
            has alarm-pheromone $ap,
            has edge-win-rate $wr,
            has from-state-id $state;
        $wr < 0.40;
        select $e, $ap, $wr, $state;
        sort $ap desc;
        limit 20;
    """,

    "recent_losing_patterns": """
        match
            $t isa trade-record,
                has trade-outcome "loss",
                has timestamp $ts,
                has trade-pnl $pnl;
            $d isa trading-decision,
                has decision-id $did;
            $t has decision-id $did;
        select $t, $ts, $pnl;
        sort $ts desc;
        limit 50;
    """,

    "high_uncertainty_edges": """
        match $e isa signal-edge,
            has confidence-width $cw,
            has win-count $wc,
            has loss-count $lc;
        $cw > 0.3;  # Wide confidence interval
        ?total = $wc + $lc;
        ?total >= 10;  # But has some data
        select $e, $cw;
        sort $cw desc;
    """,

    # === HOW AM I EVOLVING? ===

    "generation_stats": """
        match $g isa agent-genome,
            has generation $gen,
            has fitness-score $fit,
            has pnl-generated $pnl;
        reduce
            $count = count,
            $avg_gen = mean($gen),
            $max_gen = max($gen),
            $avg_fitness = mean($fit),
            $total_pnl = sum($pnl);
    """,

    "lineage_diversity": """
        match $g isa agent-genome,
            has parent-id $pid;
        $pid != "";  # Has a parent
        reduce $unique_parents = count(distinct $pid);
    """,

    "winning_traits": """
        match $g isa agent-genome,
            has fitness-score $fit,
            has pheromone-sensitivity $ps,
            has exploration-bias $eb,
            has risk-tolerance $rt;
        $fit >= 50.0;  # Above-average fitness
        reduce
            $count = count,
            $avg_pheromone_sensitivity = mean($ps),
            $avg_exploration_bias = mean($eb),
            $avg_risk_tolerance = mean($rt);
    """,

    # === WHAT SHOULD I EXPLORE? ===

    "low_sample_high_potential": """
        match $e isa signal-edge,
            has win-count $wc,
            has loss-count $lc,
            has edge-win-rate $wr;
        ?total = $wc + $lc;
        ?total < 30;       # Low sample size
        ?total >= 5;       # But not brand new
        $wr >= 0.6;        # Looks promising
        select $e, $wr;
        sort $wr desc;
    """,

    "underexplored_regimes": """
        match $e isa signal-edge,
            has from-state-id $state,
            has win-count $wc,
            has loss-count $lc;
        reduce
            $total_trades = sum($wc) + sum($lc);
        group $state;
        $total_trades < 100;
    """,

    # === EMERGENCE METRICS ===

    "emergence_score_history": """
        match $m isa emergence-metrics,
            has cycle $c,
            has emergence-score $es,
            has current-phase $phase,
            has colony-win-rate $wr;
        select $c, $es, $phase, $wr;
        sort $c desc;
        limit 100;
    """,

    "phase_transitions": """
        match $p isa phase-transition-event,
            has timestamp $ts,
            has from-phase $from,
            has to-phase $to,
            has trigger-metric $metric;
        select $ts, $from, $to, $metric;
        sort $ts desc;
    """,

    # === FEEDBACK LOOP HEALTH ===

    "feedback_loop_trend": """
        match $f isa feedback-cycle,
            has cycle-number $cn,
            has loop-ratio $lr,
            has patterns-crystallized $pc,
            has net-pnl $pnl;
        select $cn, $lr, $pc, $pnl;
        sort $cn desc;
        limit 30;
    """,

    "hypothesis_effectiveness": """
        match $h isa trading-hypothesis,
            has hypothesis-status $status,
            has observations $obs,
            has pheromone-boost $boost;
        reduce
            $total = count,
            $confirmed = count($status == "confirmed"),
            $rejected = count($status == "rejected"),
            $avg_boost = mean($boost);
    """,
}

Self-Model Dashboard

The /model command generates a complete self-model:

COLONY SELF-MODEL (generated 2026-01-15 12:00:00)
══════════════════════════════════════════════════════════════════════════

WHAT AM I GOOD AT?
──────────────────
• Best regime: trending_up (72.3% WR, 847 trades)
• Top pattern: UP1:NORM:TREN:NEUT → long (78.1% WR)
• Superhighways: 23 proven paths (avg 89.2 pheromone)
• Elite edges: 156 patterns (>75% WR, >50 trades)

WHERE AM I FAILING?
───────────────────
• Worst regime: volatile (41.2% WR, 203 trades)
• Danger zones: 12 edges with alarm > 50
• Recent losing streak: 7 consecutive losses (funding reversal)
• High uncertainty: 34 edges need more data (CI width > 0.3)

HOW AM I EVOLVING?
──────────────────
• Current generation: avg 4.2, max 12
• Lineages active: 8 distinct genetic lines
• Phylogenetic diversity: 0.67 (healthy)
• Winning traits: high pheromone_sensitivity (0.78), low exploration (0.21)
• Fitness trend: +12.3% over last 10 generations

WHAT SHOULD I EXPLORE?
──────────────────────
• High-potential low-sample: 15 edges look promising, need more trades
• Underexplored regimes: ranging (only 89 trades)
• Hypothesis queue: 8 hypotheses testing, 3 near confirmation

EMERGENCE STATUS
────────────────
• Current phase: TRANSFER
• Phase progress: 67% to DISCOVERY
• Emergence score: 0.42 (up from 0.31 last week)
• Loop ratio: 1.08 (self-sustaining for 12 cycles)

RECOMMENDATIONS
───────────────
1. Reduce position size in volatile regime
2. Focus exploration on ranging regime
3. Confirm hypothesis #7: "breakout_high fails when OI declining"
4. Potential phase transition in ~200 cycles

Extension Points

This ontology can be extended with:

  1. Multi-Asset Support: Extend State for multiple symbols
  2. Options Trading: New event types for Greeks, expiry
  3. Funding Arbitrage: Cross-exchange connections
  4. Social Signals: Integration with sentiment data
  5. ML Integration: Feature store in KNOWLEDGE dimension
  6. Portfolio Optimization: Multi-position management
  7. Risk Parity: Dynamic allocation based on volatility
  8. Regime ML: Neural regime detection models

File Layout

ants/trader/                         # 30+ files
│
├── __init__.py                      # Exports: Trader, Config
├── __main__.py                      # Entry: python -m ants.trader
├── core.py                          # Trader class (ACTOR: orchestrator)
├── config.py                        # TraderConfig, TraderState
│
├── types/                           # TypeScript type definitions
│   ├── base.ts
│   ├── groups.ts                    # GROUPS types
│   ├── actors.ts                    # ACTORS types
│   ├── things.ts                    # THINGS types
│   ├── connections.ts               # CONNECTIONS types
│   ├── events.ts                    # EVENTS types
│   └── knowledge.ts                 # KNOWLEDGE types
│
├── models/                          # Pydantic models by dimension
│   ├── __init__.py
│   ├── base.py                      # TraderModel base
│   ├── groups.py                    # GROUPS: TradingGroup, etc.
│   ├── actors.py                    # ACTORS: CognitiveActor, etc.
│   ├── things.py                    # THINGS: State, Signal, etc.
│   ├── connections.py               # CONNECTIONS: SignalEdge, etc.
│   ├── events.py                    # EVENTS: Decision, Trade, etc.
│   └── knowledge.py                 # KNOWLEDGE: Pattern, etc.
│
├── observe/                         # OBSERVE (ACTOR: perceiver)
│   ├── __init__.py
│   ├── market.py
│   ├── realtime.py
│   └── indicators.py
│
├── analyze/                         # ANALYZE (ACTOR: analyzer)
│   ├── __init__.py
│   ├── brain.py
│   └── precursor.py
│
├── decide/                          # DECIDE (ACTOR: judge)
│   ├── __init__.py
│   └── judges.py
│
├── act/                             # ACT (ACTOR: executor)
│   ├── __init__.py
│   ├── executor.py
│   └── fast_executor.py
│
├── manage/                          # Position Management
│   ├── __init__.py
│   └── position_manager.py
│
├── learn/                           # LEARN (ACTOR: learner)
│   ├── __init__.py
│   ├── memory.py
│   ├── prediction_learner.py
│   └── learning_metrics.py
│
└── queries.py                       # TypeQL query patterns

Summary: ONE Ontology × Trading

ONE Dimension Trading Concept TypeDB Entity Cognitive Layer
GROUPS Trade mission, Strategy groups trading-group (scope)
ACTORS Market, Brain, Judges, Executor, Memory, Guard cognitive-actor ALL
THINGS State, Price, Signal, PrecursorIndicator market-state, trading-signal OBSERVE, ANALYZE
CONNECTIONS SignalEdge (+confidence), RegimeTransition, PatternCorrelation signal-edge ANALYZE, LEARN
EVENTS Decision, Trade, RegimeChange, Crystallization, Prediction, Halt, Reproduction, PhaseTransition, System trading-decision, trade-record, prediction-event, halt-event, reproduction-event DECIDE, ACT, LEARN
KNOWLEDGE CrystallizedPattern, RiskProfile, Analytics, EmergenceMetrics, Genome, Hypothesis, FeedbackCycle, LineageAnalysis crystallized-pattern, emergence-metrics, agent-genome, trading-hypothesis, feedback-cycle LEARN, EVOLVE

Emergence Additions (v3.1.0)

Category New Entity Purpose
Measurement EmergenceMetrics Track emergence_score, phase transitions
Evolution Genome, LineageAnalysis Heritable traits, phylogenetic tracking
Meta-Learning Hypothesis Test beliefs: "pattern X fails when Y"
Feedback Loop FeedbackCycle Track self-funding loop closure
Uncertainty SignalEdge confidence Bayesian credible intervals (avoid overfitting)
Events Prediction, Halt, Reproduction, PhaseTransition, System Complete audit trail
Self-Model SELF_MODEL_QUERIES Colony knows itself

The key insight: The cognitive loop is a process that operates on the ONE dimensions. Each component is an ACTOR that reads/writes to specific dimensions.

Intelligence emerges from:

  • Pheromone trails (CONNECTIONS) accumulating over thousands of trades
  • TypeDB inference rules deriving tiers and crystallization candidates
  • Patterns crystallizing into permanent KNOWLEDGE
  • Cross-mission transfer spreading successful strategies
  • Evolutionary dynamics (Genome, LineageAnalysis) selecting for intelligence
  • Meta-learning (Hypothesis) refining what works and when
  • Feedback loop (FeedbackCycle) closing the self-funding loop
  • Self-model enabling recursive improvement

Emergence is now measurable: emergence_score > 0 means colony intelligence exceeds sum of individuals.

This is stigmergic trading: the environment holds the intelligence, not the agents.


Multi-Asset + Multi-User Architecture (v3.6.0)

Phase 2 Evolution: From single-asset single-user to hundreds of pairs with any connected wallet.

The Vision

┌─────────────────────────────────────────────────────────────────────────────┐
│                    MULTI-TENANT TRADING PLATFORM                            │
│                                                                             │
│  ANY USER                    ANY SYMBOL                  SHARED INTELLIGENCE│
│  ─────────                   ──────────                  ──────────────────│
│  Connect wallet              100+ Hyperliquid pairs      Pheromone trails   │
│  Set risk prefs              BTC, ETH, SOL, ARB...       transfer across    │
│  Auto-trading                Per-symbol state space      users & symbols    │
│                                                                             │
│  ONE Ontology GROUPS provide:                                               │
│  ├── User isolation (each user = own group)                                │
│  ├── Symbol scoping (pheromones per symbol)                                │
│  └── Shared knowledge (crystallized patterns transfer)                     │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Group Hierarchy (ONE Ontology)

Platform (ants-platform)
└── Colony (genesis-001)
    └── Trade Mission (trade)
        │
        ├── Symbol Groups (per-asset pheromone isolation)
        │   ├── symbol:BTC-PERP
        │   ├── symbol:ETH-PERP
        │   ├── symbol:SOL-PERP
        │   ├── symbol:ARB-PERP
        │   └── ... (100+ symbols)
        │
        └── User Groups (per-user trading isolation)
            ├── user:alice-0x1234...
            │   ├── Wallet connection
            │   ├── Risk preferences
            │   ├── Allowed symbols
            │   └── Trading history (EVENTS)
            │
            ├── user:bob-0x5678...
            │   └── ...
            │
            └── user:... (unlimited users)

ISOLATION RULES:
────────────────
• Pheromone trails are GLOBAL (shared intelligence)
• User positions are ISOLATED (own wallet)
• Crystallized patterns are SHARED (collective wisdom)
• Risk settings are USER-SCOPED

New Group Types

// ants/trader/types/groups.ts (ASPIRATIONAL)

export type TradingGroupType =
  | "trade_mission"      // Root mission container
  | "strategy_group"     // Strategy-specific grouping
  | "risk_tier"          // Risk level grouping
  | "regime_group"       // Regime-specific grouping
  | "symbol_group"       // NEW: Per-symbol isolation
  | "user_group";        // NEW: Per-user isolation

/**
 * Symbol Group — pheromone isolation per trading pair.
 *
 * Each symbol has its own state space (3,600 states × symbol).
 * Pheromones don't cross symbols, but PATTERNS can transfer.
 */
export interface SymbolGroup extends TradingGroup {
  type: "symbol_group";
  properties: TradingGroup["properties"] & {
    symbol: {
      name: string;              // "BTC-PERP", "ETH-PERP", etc.
      exchange: "hyperliquid";
      baseAsset: string;         // "BTC", "ETH"
      quoteAsset: string;        // "USDC"

      // Symbol-specific settings
      minSize: number;           // Minimum order size
      tickSize: number;          // Price tick
      maxLeverage: number;       // Exchange max leverage

      // Colony-learned parameters
      avgVolatility: number;     // Historical volatility
      correlatedSymbols: string[]; // Correlated pairs
      optimalTimeframes: string[]; // Best timeframes for this symbol
    };

    // Symbol-level metrics
    metrics: {
      totalEdges: number;        // SignalEdges for this symbol
      superhighways: number;     // Crystallized paths
      activeUsers: number;       // Users trading this symbol
      dailyVolume: number;       // 24h volume in USDC
    };
  };
}

/**
 * User Group — per-user trading isolation.
 *
 * Each user connects their Hyperliquid wallet.
 * We trade on their behalf with THEIR capital.
 * They set their own risk preferences.
 */
export interface UserGroup extends TradingGroup {
  type: "user_group";
  properties: TradingGroup["properties"] & {
    user: {
      userId: string;            // Internal ID
      walletAddress: string;     // 0x... Hyperliquid wallet
      displayName?: string;

      // Connection status
      connectedAt: Date;
      lastActiveAt: Date;
      isActive: boolean;

      // Delegation (they delegate trading authority to us)
      delegationType: "full" | "signals_only" | "manual_confirm";
      delegatedAt: Date;
      delegationExpires?: Date;
    };

    // User's risk preferences
    risk: {
      maxPositionSize: number;   // Max % of portfolio per trade
      maxTotalExposure: number;  // Max % total exposure
      maxLeverage: number;       // User's max leverage (≤ exchange max)
      allowedSymbols: string[];  // Symbols user wants to trade (or "*" for all)
      blockedSymbols: string[];  // Symbols to never trade

      dailyLossLimit: number;    // Stop trading if daily loss exceeds
      weeklyLossLimit: number;   // Stop trading if weekly loss exceeds

      minConfidence: number;     // Only trade signals above this confidence
      minPheromone: number;      // Only follow trails above this level
    };

    // User's trading stats
    stats: {
      totalTrades: number;
      winRate: number;
      totalPnL: number;
      bestSymbol: string;
      worstSymbol: string;
      memberSince: Date;
    };
  };
}
# ants/trader/models/groups.py (additions)

class TradingGroupType(str, Enum):
    TRADE_MISSION = "trade_mission"
    STRATEGY_GROUP = "strategy_group"
    RISK_TIER = "risk_tier"
    REGIME_GROUP = "regime_group"
    SYMBOL_GROUP = "symbol_group"      # NEW
    USER_GROUP = "user_group"          # NEW


class SymbolConfig(TraderModel):
    """Symbol-specific configuration."""
    name: str                          # "BTC-PERP"
    exchange: str = "hyperliquid"
    base_asset: str                    # "BTC"
    quote_asset: str = "USDC"

    min_size: float
    tick_size: float
    max_leverage: float = 50.0

    avg_volatility: float = 0.0
    correlated_symbols: List[str] = Field(default_factory=list)
    optimal_timeframes: List[str] = Field(default_factory=lambda: ["1h", "4h"])


class SymbolGroup(TradingGroup):
    """
    Per-symbol pheromone isolation.

    ONE Dimension: GROUPS
    TypeDB Entity: symbol-group
    """
    group_type: TradingGroupType = TradingGroupType.SYMBOL_GROUP
    symbol: SymbolConfig

    total_edges: int = 0
    superhighways: int = 0
    active_users: int = 0
    daily_volume: float = 0.0

    @classmethod
    def from_hyperliquid(cls, symbol_info: dict) -> "SymbolGroup":
        """Create from Hyperliquid API response."""
        return cls(
            name=symbol_info["name"],
            symbol=SymbolConfig(
                name=symbol_info["name"],
                base_asset=symbol_info["name"].replace("-PERP", ""),
                min_size=float(symbol_info.get("minSz", 0.001)),
                tick_size=float(symbol_info.get("tickSz", 0.1)),
                max_leverage=float(symbol_info.get("maxLeverage", 50)),
            )
        )


class UserRiskPreferences(TraderModel):
    """User's personal risk settings."""
    max_position_size: float = Field(ge=0.01, le=1.0, default=0.1)  # 10% default
    max_total_exposure: float = Field(ge=0.1, le=1.0, default=0.5)  # 50% max
    max_leverage: float = Field(ge=1, le=50, default=5)

    allowed_symbols: List[str] = Field(default_factory=lambda: ["*"])  # All
    blocked_symbols: List[str] = Field(default_factory=list)

    daily_loss_limit: float = Field(ge=0.01, le=0.5, default=0.05)   # 5%
    weekly_loss_limit: float = Field(ge=0.01, le=0.5, default=0.15)  # 15%

    min_confidence: float = Field(ge=0.5, le=1.0, default=0.6)
    min_pheromone: float = Field(ge=0, le=100, default=60)


class UserDelegation(TraderModel):
    """Trading authority delegation."""
    delegation_type: str = "full"  # full, signals_only, manual_confirm
    delegated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    delegation_expires: Optional[datetime] = None

    @property
    def is_active(self) -> bool:
        if self.delegation_expires is None:
            return True
        return datetime.now(timezone.utc) < self.delegation_expires


class UserGroup(TradingGroup):
    """
    Per-user trading isolation.

    Users connect their Hyperliquid wallet and delegate trading authority.
    We trade on their behalf with THEIR capital.

    ONE Dimension: GROUPS
    TypeDB Entity: user-group
    """
    group_type: TradingGroupType = TradingGroupType.USER_GROUP

    user_id: str
    wallet_address: str                # 0x... Hyperliquid wallet
    display_name: Optional[str] = None

    connected_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    last_active_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    is_active: bool = True

    delegation: UserDelegation = Field(default_factory=UserDelegation)
    risk: UserRiskPreferences = Field(default_factory=UserRiskPreferences)

    # Stats
    total_trades: int = 0
    win_rate: float = 0.5
    total_pnl: float = 0.0
    best_symbol: Optional[str] = None
    worst_symbol: Optional[str] = None

    def can_trade_symbol(self, symbol: str) -> bool:
        """Check if user allows trading this symbol."""
        if symbol in self.risk.blocked_symbols:
            return False
        if "*" in self.risk.allowed_symbols:
            return True
        return symbol in self.risk.allowed_symbols

    def check_risk_limits(self, daily_pnl: float, weekly_pnl: float) -> tuple[bool, str]:
        """Check if user has hit risk limits."""
        if daily_pnl <= -self.risk.daily_loss_limit:
            return False, f"Daily loss limit hit: {daily_pnl:.2%}"
        if weekly_pnl <= -self.risk.weekly_loss_limit:
            return False, f"Weekly loss limit hit: {weekly_pnl:.2%}"
        return True, "OK"

Profit Share Model (10% of Winning Trades)

Revenue Model: We take 10% of profits on winning trades. No fees on losses.

┌─────────────────────────────────────────────────────────────────────────────┐
│                         PROFIT SHARE MODEL                                  │
│                                                                             │
│   User wins trade:     User gets 90%    │    Colony gets 10%               │
│   User loses trade:    User pays 100%   │    Colony gets 0%                │
│                                                                             │
│   Example:                                                                  │
│   ─────────                                                                 │
│   Trade profit: +$100                                                       │
│   User receives: $90                                                        │
│   Colony fee: $10                                                           │
│                                                                             │
│   Trade loss: -$50                                                          │
│   User pays: -$50                                                           │
│   Colony fee: $0                                                            │
│                                                                             │
│   WHY THIS MODEL:                                                           │
│   ├── Aligned incentives (we only win when users win)                      │
│   ├── No upfront fees (users can try risk-free)                            │
│   ├── Sustainable revenue (grows with user success)                        │
│   └── Fair (we share downside via lost opportunity)                        │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
// ants/trader/types/fees.ts (ASPIRATIONAL)

export interface FeeConfig {
  // Profit share
  profitSharePercent: number;      // 10% = 0.10
  minProfitForFee: number;         // Min profit to charge fee (e.g., $1)

  // Fee collection
  feeWalletAddress: string;        // Colony's fee wallet
  feeCollectionMethod: "immediate" | "daily" | "weekly";

  // Discounts (optional future feature)
  volumeDiscountTiers?: {
    minVolume: number;             // 30d volume threshold
    discountPercent: number;       // Fee discount
  }[];
}

export interface TradeFee {
  feeId: string;
  tradeId: string;
  userId: string;

  // Amounts
  grossProfit: number;             // User's raw profit
  feeAmount: number;               // Our 10%
  netProfit: number;               // User keeps this (90%)

  // Status
  status: "pending" | "collected" | "failed";
  collectedAt?: Date;
  txHash?: string;                 // On-chain proof
}
# ants/trader/models/fees.py (ASPIRATIONAL - simplified version implemented)

class FeeConfig(TraderModel):
    """
    Colony fee configuration.

    Default: 10% of profits on winning trades.
    """
    profit_share_percent: float = Field(ge=0, le=0.5, default=0.10)  # 10%
    min_profit_for_fee: float = Field(ge=0, default=1.0)  # $1 minimum

    fee_wallet_address: str = ""  # Colony's fee collection wallet
    fee_collection_method: str = "immediate"  # immediate, daily, weekly

    @computed_field
    @property
    def user_share_percent(self) -> float:
        """User's share of profits."""
        return 1.0 - self.profit_share_percent


class TradeFee(TraderModel):
    """
    Fee record for a profitable trade.

    ONE Dimension: EVENTS
    TypeDB Entity: trade-fee
    """
    fee_id: str = ""
    trade_id: str
    user_id: str

    # Amounts
    gross_profit: float            # Raw profit
    fee_amount: float              # Our 10%
    net_profit: float              # User's 90%

    # Status
    status: str = "pending"        # pending, collected, failed
    collected_at: Optional[datetime] = None
    tx_hash: Optional[str] = None

    def model_post_init(self, __context) -> None:
        if not self.fee_id:
            self.fee_id = f"fee-{self.trade_id}"

    @classmethod
    def from_trade(cls, trade: "Trade", user_id: str, fee_config: FeeConfig) -> Optional["TradeFee"]:
        """
        Create fee record from a closed trade.

        Returns None if trade was not profitable or below minimum.
        """
        if trade.realized_pnl <= 0:
            return None  # No fee on losses

        if trade.realized_pnl < fee_config.min_profit_for_fee:
            return None  # Below minimum

        fee_amount = trade.realized_pnl * fee_config.profit_share_percent
        net_profit = trade.realized_pnl - fee_amount

        return cls(
            trade_id=trade.trade_id,
            user_id=user_id,
            gross_profit=trade.realized_pnl,
            fee_amount=fee_amount,
            net_profit=net_profit,
        )


class FeeCollector:
    """
    Collect fees from profitable trades.

    Options:
    1. Immediate: Deduct from each winning trade
    2. Daily: Batch collect at end of day
    3. Weekly: Batch collect at end of week
    """

    def __init__(self, fee_config: FeeConfig, db_client):
        self.config = fee_config
        self.db = db_client

    async def process_trade(self, trade: "Trade", user: UserGroup) -> Optional[TradeFee]:
        """Process fee for a completed trade."""
        fee = TradeFee.from_trade(trade, user.user_id, self.config)

        if fee is None:
            return None

        # Record fee
        await self.db.insert_fee(fee)

        # Collect based on method
        if self.config.fee_collection_method == "immediate":
            await self._collect_immediate(fee, user)

        return fee

    async def _collect_immediate(self, fee: TradeFee, user: UserGroup):
        """
        Collect fee immediately after winning trade.

        Implementation depends on Hyperliquid's transfer API.
        For now, we track it and collect manually or via separate tx.
        """
        # Option 1: User pre-authorizes fee deduction
        # Option 2: We track and invoice periodically
        # Option 3: Smart contract escrow (future)

        fee.status = "pending"  # Will be collected in next batch
        await self.db.update_fee(fee)

    async def collect_pending_fees(self) -> List[TradeFee]:
        """Batch collect all pending fees."""
        pending = await self.db.get_pending_fees()

        collected = []
        for fee in pending:
            try:
                # Transfer from user to colony wallet
                # (Requires user to have granted transfer permission)
                # tx_hash = await self._transfer_fee(fee)

                fee.status = "collected"
                fee.collected_at = datetime.now(timezone.utc)
                # fee.tx_hash = tx_hash
                await self.db.update_fee(fee)
                collected.append(fee)
            except Exception as e:
                fee.status = "failed"
                await self.db.update_fee(fee)

        return collected
# === FEE SCHEMA ===

attribute fee-id, value string;
attribute gross-profit, value double;
attribute fee-amount, value double;
attribute net-profit, value double;
attribute fee-status, value string;
attribute collected-at, value datetime;
attribute tx-hash, value string;

entity trade-fee,
    owns fee-id @key,
    owns gross-profit,
    owns fee-amount,
    owns net-profit,
    owns fee-status,
    owns collected-at,
    owns tx-hash;

relation fee-for-trade,
    relates fee,
    relates trade,
    relates user;

trade-fee plays fee-for-trade:fee;
trade-record plays fee-for-trade:trade;
trading-user plays fee-for-trade:user;

# Get total fees collected
fun get_total_fees_collected() -> double:
    match
        $f isa trade-fee, has fee-amount $amt, has fee-status "collected";
    reduce $total = sum($amt);
    return $total;

# Get user's total fees paid
fun get_user_fees($user_id: string) -> double:
    match
        $u isa trading-user, has user-id $user_id;
        $rel (fee: $f, user: $u) isa fee-for-trade;
        $f has fee-amount $amt;
    reduce $total = sum($amt);
    return $total;

Symbol-Scoped SignalEdge

The fundamental change: SignalEdge is now scoped by symbol.

// ants/trader/types/connections.ts (ASPIRATIONAL) (updated)

export interface SignalEdge {
  edgeId: string;
  symbol: string;               // NEW: "BTC-PERP", "ETH-PERP", etc.
  fromStateId: string;          // Discretized state (symbol-specific)
  toDirection: Direction;

  // ... rest unchanged
}
# ants/trader/models/connections.py (ASPIRATIONAL - symbol field implemented as symbol_name)

class SignalEdge(TraderModel):
    """
    Pheromone edge - NOW SYMBOL-SCOPED.

    Each symbol has its own pheromone landscape.
    State space: 3,600 states × N symbols × 3 directions = millions of edges
    """
    edge_id: str = ""
    symbol: str = "BTC-PERP"           # Implemented as symbol_name in code
    from_state_id: str
    to_direction: Direction

    # ... rest unchanged

    def model_post_init(self, __context) -> None:
        if not self.edge_id:
            # Include symbol in edge ID
            self.edge_id = f"{self.symbol}:{self.from_state_id}:{self.to_direction.value}"

User Entity (ACTORS)

// ants/trader/types/actors.ts (ASPIRATIONAL)

/**
 * User Actor — a human who delegates trading to the colony.
 *
 * ONE Dimension: ACTORS
 * TypeDB Entity: trading-user
 */
export interface TradingUser {
  userId: string;
  walletAddress: string;

  // Actor properties
  actorType: "human";
  role: "delegator";            // Delegates trading authority

  // Connection
  connectedAt: Date;
  lastActiveAt: Date;

  // What they've delegated
  delegation: {
    type: "full" | "signals_only" | "manual_confirm";
    symbols: string[];          // Which symbols they allow
    maxPositionSize: number;
    maxLeverage: number;
  };

  // Their wallet state (READ from Hyperliquid)
  walletState: {
    equity: number;
    freeCollateral: number;
    openPositions: number;
    unrealizedPnL: number;
  };
}
# ants/trader/models/actors.py (ASPIRATIONAL - simplified version in models.py)
# NOTE: Actual TradingUser in code has fewer fields (no actor_type, role, wallet state)

class TradingUser(TraderModel):
    """
    Human user who delegates trading to the colony.

    ONE Dimension: ACTORS
    TypeDB Entity: trading-user
    """
    user_id: str
    wallet_address: str

    actor_type: str = "human"
    role: str = "delegator"

    connected_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    last_active_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Delegation
    delegation_type: str = "full"
    allowed_symbols: List[str] = Field(default_factory=lambda: ["*"])
    max_position_size: float = 0.1
    max_leverage: float = 5.0

    # Wallet state (cached, refreshed periodically)
    equity: float = 0.0
    free_collateral: float = 0.0
    open_positions: int = 0
    unrealized_pnl: float = 0.0

    @classmethod
    def dimension(cls) -> str:
        return "actors"

User-Scoped Events

// ants/trader/types/events.ts (ASPIRATIONAL) (additions)

/**
 * User-scoped trade execution.
 * Every trade belongs to a user.
 */
export interface UserTrade extends Trade {
  userId: string;               // Who this trade is for
  walletAddress: string;        // Their wallet

  // User's state at time of trade
  userEquityBefore: number;
  userEquityAfter: number;
  userDailyPnL: number;
  userWeeklyPnL: number;
}

/**
 * User connection event.
 */
export interface UserConnectedEvent {
  eventId: string;
  eventType: "user_connected";
  timestamp: Date;

  userId: string;
  walletAddress: string;
  delegationType: string;
  allowedSymbols: string[];
}

/**
 * User disconnection event.
 */
export interface UserDisconnectedEvent {
  eventId: string;
  eventType: "user_disconnected";
  timestamp: Date;

  userId: string;
  reason: "voluntary" | "risk_limit" | "expiry" | "admin";
  finalPnL: number;
  totalTrades: number;
}

TypeDB Schema (Multi-Asset + Multi-User)

# === MULTI-ASSET SCHEMA ===

attribute symbol-name, value string;
attribute base-asset, value string;
attribute quote-asset, value string;
attribute min-size, value double;
attribute tick-size, value double;
attribute max-leverage, value double;
attribute avg-volatility, value double;

entity symbol-group,
    owns group-id @key,
    owns symbol-name @card(1),
    owns base-asset,
    owns quote-asset,
    owns min-size,
    owns tick-size,
    owns max-leverage,
    owns avg-volatility,
    owns created-at;

# Update signal-edge to be symbol-scoped
entity signal-edge,
    owns edge-id @key,
    owns symbol-name @card(1),           # NEW: Symbol scoping
    owns from-state-id @card(1),
    owns to-direction @card(1),
    owns win-count,
    owns loss-count,
    owns total-pnl,
    owns trail-pheromone,
    owns alarm-pheromone,
    owns tier,
    owns created-at,
    owns updated-at;


# === MULTI-USER SCHEMA ===

attribute user-id, value string;
attribute wallet-address, value string;
attribute display-name, value string;
attribute delegation-type, value string;
attribute max-position-size, value double;
attribute daily-loss-limit, value double;
attribute weekly-loss-limit, value double;
attribute min-confidence, value double;
attribute min-pheromone-threshold, value double;
attribute connected-at, value datetime;
attribute last-active-at, value datetime;
attribute is-active, value boolean;

entity trading-user,
    owns user-id @key,
    owns wallet-address @card(1),
    owns display-name,
    owns delegation-type,
    owns max-position-size,
    owns max-leverage,
    owns daily-loss-limit,
    owns weekly-loss-limit,
    owns min-confidence,
    owns min-pheromone-threshold,
    owns connected-at,
    owns last-active-at,
    owns is-active;

entity user-group,
    owns group-id @key,
    owns user-id @card(1),
    owns parent-group-id,
    owns created-at;

# User's allowed/blocked symbols
relation user-symbol-permission,
    relates user,
    relates symbol,
    owns permission-type;  # "allowed" or "blocked"

trading-user plays user-symbol-permission:user;
symbol-group plays user-symbol-permission:symbol;

# User's trade history
relation user-trade,
    relates user,
    relates trade;

trading-user plays user-trade:user;
trade-record plays user-trade:trade;


# === QUERIES FOR MULTI-USER ===

# Get all active users
fun get_active_users() -> { trading-user }:
    match $u isa trading-user, has is-active true;
    return { $u };

# Get user's allowed symbols
fun get_user_symbols($user_id: string) -> { symbol-group }:
    match
        $u isa trading-user, has user-id $user_id;
        $perm (user: $u, symbol: $s) isa user-symbol-permission,
            has permission-type "allowed";
    return { $s };

# Get best edges for symbol (user-filtered by confidence)
fun get_edges_for_user($symbol: string, $min_conf: double) -> { signal-edge }:
    match
        $e isa signal-edge,
            has symbol-name $symbol,
            has trail-pheromone $tp,
            has win-count $wc,
            has loss-count $lc;
        $tp >= $min_conf * 100;
        let $total = $wc + $lc;
        $total >= 20;
    sort $tp desc;
    return { $e };

# Get user's P&L for risk checks
fun get_user_daily_pnl($user_id: string) -> double:
    match
        $u isa trading-user, has user-id $user_id;
        $ut (user: $u, trade: $t) isa user-trade;
        $t has trade-timestamp $ts, has realized-pnl $pnl;
        # Filter to today (pseudo-code)
    reduce $total = sum($pnl);
    return $total;

Hyperliquid Symbol Discovery

# ants/trader/observe/symbols.py

from typing import List
import httpx

HYPERLIQUID_INFO_URL = "https://api.hyperliquid.xyz/info"  # Mainnet
HYPERLIQUID_TESTNET_URL = "https://api.hyperliquid-testnet.xyz/info"


async def get_all_symbols(testnet: bool = True) -> List[dict]:
    """
    Fetch all available perpetual symbols from Hyperliquid.

    Returns ~100+ symbols with their configuration.
    """
    url = HYPERLIQUID_TESTNET_URL if testnet else HYPERLIQUID_INFO_URL

    async with httpx.AsyncClient() as client:
        response = await client.post(url, json={"type": "meta"})
        meta = response.json()

    symbols = []
    for asset_info in meta.get("universe", []):
        symbols.append({
            "name": asset_info["name"],
            "szDecimals": asset_info.get("szDecimals", 3),
            "maxLeverage": asset_info.get("maxLeverage", 50),
        })

    return symbols


async def initialize_symbol_groups(db_client, testnet: bool = True):
    """
    Create SymbolGroup for each Hyperliquid symbol.

    Run once on startup or when new symbols are added.
    """
    symbols = await get_all_symbols(testnet)

    for sym in symbols:
        group = SymbolGroup.from_hyperliquid(sym)
        await db_client.upsert_symbol_group(group)

    return len(symbols)

User Wallet Connection Flow

# ants/trader/manage/user_manager.py

from typing import Optional
from hyperliquid.info import Info


class UserManager:
    """
    Manage user connections and delegations.

    Flow:
    1. User connects wallet (frontend)
    2. User signs delegation message
    3. We create UserGroup in TypeDB
    4. We start trading for them (respecting their limits)
    """

    def __init__(self, db_client, testnet: bool = True):
        self.db = db_client
        self.info = Info(
            "https://api.hyperliquid-testnet.xyz" if testnet
            else "https://api.hyperliquid.xyz",
            skip_ws=True
        )

    async def connect_user(
        self,
        wallet_address: str,
        delegation_type: str = "full",
        risk_prefs: Optional[UserRiskPreferences] = None,
    ) -> UserGroup:
        """
        Connect a new user wallet.

        1. Verify wallet exists on Hyperliquid
        2. Create UserGroup
        3. Record connection event
        """
        # Verify wallet has funds
        state = self.info.user_state(wallet_address)
        if float(state.get("marginSummary", {}).get("accountValue", 0)) <= 0:
            raise ValueError("Wallet has no funds on Hyperliquid")

        # Create user
        user_id = f"user-{wallet_address[:8]}-{int(time.time())}"

        user_group = UserGroup(
            name=f"User {wallet_address[:8]}",
            user_id=user_id,
            wallet_address=wallet_address,
            delegation=UserDelegation(delegation_type=delegation_type),
            risk=risk_prefs or UserRiskPreferences(),
        )

        # Save to TypeDB
        await self.db.upsert_user_group(user_group)

        # Record event
        await self.db.insert_event({
            "event_type": "user_connected",
            "user_id": user_id,
            "wallet_address": wallet_address,
            "delegation_type": delegation_type,
        })

        return user_group

    async def disconnect_user(self, user_id: str, reason: str = "voluntary"):
        """Disconnect user and stop trading for them."""
        user = await self.db.get_user_group(user_id)
        if not user:
            return

        # Calculate final stats
        stats = await self.db.get_user_stats(user_id)

        # Mark inactive
        user.is_active = False
        await self.db.upsert_user_group(user)

        # Record event
        await self.db.insert_event({
            "event_type": "user_disconnected",
            "user_id": user_id,
            "reason": reason,
            "final_pnl": stats.get("total_pnl", 0),
            "total_trades": stats.get("total_trades", 0),
        })

    async def get_tradeable_users(self, symbol: str) -> List[UserGroup]:
        """Get all active users who can trade this symbol."""
        users = await self.db.get_active_users()
        return [u for u in users if u.can_trade_symbol(symbol)]

    async def check_user_risk(self, user_id: str) -> tuple[bool, str]:
        """Check if user can continue trading."""
        user = await self.db.get_user_group(user_id)
        if not user or not user.is_active:
            return False, "User not active"

        daily_pnl = await self.db.get_user_daily_pnl(user_id)
        weekly_pnl = await self.db.get_user_weekly_pnl(user_id)

        return user.check_risk_limits(daily_pnl, weekly_pnl)

Trading Loop (Multi-User)

# ants/trader/core.py (updated)

class Trader:
    """
    The unified trading mind - NOW MULTI-USER.

    Trades for ALL connected users simultaneously.
    Each user has their own risk limits.
    Pheromone intelligence is SHARED.
    """

    async def run(self):
        """Multi-user trading loop."""
        await self._connect_all()

        while self.alive and not self.state.halted:
            # Get all symbols we're tracking
            symbols = await self.symbol_manager.get_active_symbols()

            for symbol in symbols:
                # OBSERVE - What do I see?
                state: State = await self.market.observe(symbol)

                # ANALYZE - What do I think? (SHARED pheromones)
                signal: Signal = await self.brain.analyze(state, symbol)

                if not signal.is_actionable:
                    continue

                # Get users who can trade this symbol
                users = await self.user_manager.get_tradeable_users(symbol)

                for user in users:
                    # Check user-specific risk
                    can_trade, reason = await self.user_manager.check_user_risk(user.user_id)
                    if not can_trade:
                        continue

                    # Check user's confidence threshold
                    if signal.confidence < user.risk.min_confidence:
                        continue

                    # DECIDE - Should I act for THIS user?
                    decision = await self.judges.decide(signal, state, user)

                    if decision.approved:
                        # ACT - Execute for THIS user's wallet
                        trade = await self.executor.act(decision, user)

                        # LEARN - Deposit pheromones (SHARED)
                        await self.memory.learn(state, signal, decision, trade)

Summary: Multi-Asset + Multi-User

Component Single-User Multi-User
Symbol BTC-PERP only 100+ Hyperliquid pairs
SignalEdge Global Symbol-scoped
State Space 3,600 states 3,600 × N symbols
Users Tony only Any connected wallet
Risk Limits Global Per-user
Pheromones Global Symbol-scoped, user-shared
Patterns Per-mission Per-symbol, transferable
Wallet Hardcoded Dynamic delegation

The Key Insight: Pheromone intelligence is SHARED across users, but execution is ISOLATED. Every user benefits from collective wisdom while maintaining their own risk boundaries.


Cross-Symbol Morphic Resonance (v3.6.1)

"The market follows BTC" — This is not just observation, it's exploitable alpha encoded in pheromone resonance.

The Correlation Reality

┌─────────────────────────────────────────────────────────────────────────────┐
│                    CRYPTO MARKET STRUCTURE                                  │
│                                                                             │
│                           ┌─────────┐                                       │
│                           │   BTC   │  ← KING (leads everything)            │
│                           └────┬────┘                                       │
│                                │                                            │
│              ┌─────────────────┼─────────────────┐                          │
│              │                 │                 │                          │
│         ┌────▼────┐       ┌────▼────┐       ┌────▼────┐                     │
│         │   ETH   │       │  SOL    │       │  Other  │  ← L1s lag 1-3 bars │
│         └────┬────┘       └────┬────┘       └─────────┘                     │
│              │                 │                                            │
│    ┌─────────┴───┐    ┌───────┴───────┐                                    │
│    │             │    │               │                                     │
│ ┌──▼──┐     ┌────▼──┐ │  ┌─────┐ ┌────▼┐                                   │
│ │ L2s │     │ DeFi  │ │  │ Meme│ │ AI  │  ← Sectors lag 2-5 bars           │
│ │ARB  │     │ UNI   │ │  │PEPE │ │ FET │                                    │
│ │OP   │     │ AAVE  │ │  │DOGE │ │RENDER│                                   │
│ └─────┘     └───────┘ │  └─────┘ └─────┘                                    │
│                       │                                                     │
│                  ┌────▼────┐                                                │
│                  │SOL Memes│  ← SOL ecosystem lags SOL                      │
│                  │ WIF,BONK│                                                │
│                  └─────────┘                                                │
│                                                                             │
│  LEAD-LAG STRUCTURE:                                                        │
│  BTC → ETH (1-2 candles) → L1s (2-3) → Sectors (3-5) → Ecosystem (4-6)     │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Morphic Resonance Architecture

Instead of isolated symbol pheromones, we implement resonant fields where:

  1. BTC is the heartbeat - Its pheromone state radiates to all
  2. Correlation groups share intelligence - L1s learn from each other
  3. Lead-lag relationships create predictive power - BTC signal → SOL action
  4. Sector rotation patterns crystallize - "When DeFi dumps, memes pump"
RESONANCE TYPES
═══════════════════════════════════════════════════════════════════════════════

TYPE               │ MECHANISM                    │ STRENGTH │ DECAY
───────────────────┼──────────────────────────────┼──────────┼────────
BTC Dominance      │ BTC pheromone → all symbols  │ 0.8      │ 0.99
Sector Correlation │ Same sector shares signals   │ 0.6      │ 0.95
Ecosystem          │ Base chain → ecosystem       │ 0.7      │ 0.97
Inverse            │ Risk-on/risk-off pairs       │ -0.5     │ 0.90
Lead-Lag           │ Leader signal → laggard      │ Variable │ 0.95

TypeScript Types

// ants/trader/types/resonance.ts (ASPIRATIONAL)

export type ResonanceType =
  | "btc_dominance"      // BTC → everything
  | "sector"             // Same sector correlation
  | "ecosystem"          // Base chain → tokens
  | "inverse"            // Negative correlation (BTC ↑ → USDT perps ↓)
  | "lead_lag";          // Temporal correlation

export type MarketSector =
  | "l1"                 // Layer 1s: ETH, SOL, AVAX, NEAR, SUI
  | "l2"                 // Layer 2s: ARB, OP, STRK, ZK
  | "defi"               // DeFi: UNI, AAVE, MKR, CRV
  | "ai"                 // AI: FET, RENDER, AGIX, TAO
  | "meme"               // Memes: DOGE, SHIB, PEPE, WIF, BONK
  | "gaming"             // Gaming: IMX, GALA, AXS
  | "infra"              // Infra: LINK, GRT, FIL
  | "btc_eco";           // BTC ecosystem: STX, ORDI

export interface CorrelationGroup {
  groupId: string;
  name: string;
  sector: MarketSector;
  symbols: string[];

  // Correlation matrix within group
  correlationMatrix: Record<string, Record<string, number>>;

  // Group-level metrics
  avgCorrelation: number;
  leadSymbol: string;              // Which symbol leads in this group
  avgLagCandles: number;           // How many candles laggards trail
}

export interface LeadLagRelationship {
  relationId: string;
  leaderSymbol: string;            // e.g., "BTC-PERP"
  followerSymbol: string;          // e.g., "SOL-PERP"

  // Correlation strength
  correlation: number;             // 0.0 to 1.0 (or negative)
  lagCandles: number;              // How many candles follower lags

  // Historical accuracy
  accuracy: number;                // % of times follower followed
  sampleSize: number;

  // Pheromone transfer
  resonanceStrength: number;       // How much pheromone transfers
}

export interface MorphicResonanceEvent {
  eventId: string;
  timestamp: Date;

  // Source signal
  sourceSymbol: string;
  sourceEdgeId: string;
  sourceDirection: Direction;
  sourcePheromone: number;

  // Resonance targets
  targets: {
    symbol: string;
    edgeId: string;
    resonanceType: ResonanceType;
    transferAmount: number;        // Pheromone transferred
    expectedLag: number;           // Candles until effect
  }[];
}

Pydantic Models

# ants/trader/models/resonance.py (ASPIRATIONAL - not yet implemented)
# NOTE: LeadLagRelationship and CorrelationGroup defined but not in code

from enum import Enum
from typing import Dict, List, Optional
from pydantic import Field, computed_field


class MarketSector(str, Enum):
    L1 = "l1"
    L2 = "l2"
    DEFI = "defi"
    AI = "ai"
    MEME = "meme"
    GAMING = "gaming"
    INFRA = "infra"
    BTC_ECO = "btc_eco"


class ResonanceType(str, Enum):
    BTC_DOMINANCE = "btc_dominance"
    SECTOR = "sector"
    ECOSYSTEM = "ecosystem"
    INVERSE = "inverse"
    LEAD_LAG = "lead_lag"


# Symbol → Sector mapping
SYMBOL_SECTORS: Dict[str, MarketSector] = {
    # L1s
    "ETH-PERP": MarketSector.L1,
    "SOL-PERP": MarketSector.L1,
    "AVAX-PERP": MarketSector.L1,
    "NEAR-PERP": MarketSector.L1,
    "SUI-PERP": MarketSector.L1,
    "APT-PERP": MarketSector.L1,

    # L2s
    "ARB-PERP": MarketSector.L2,
    "OP-PERP": MarketSector.L2,
    "STRK-PERP": MarketSector.L2,

    # DeFi
    "UNI-PERP": MarketSector.DEFI,
    "AAVE-PERP": MarketSector.DEFI,
    "MKR-PERP": MarketSector.DEFI,
    "CRV-PERP": MarketSector.DEFI,
    "LDO-PERP": MarketSector.DEFI,

    # AI
    "FET-PERP": MarketSector.AI,
    "RENDER-PERP": MarketSector.AI,
    "TAO-PERP": MarketSector.AI,

    # Memes
    "DOGE-PERP": MarketSector.MEME,
    "SHIB-PERP": MarketSector.MEME,
    "PEPE-PERP": MarketSector.MEME,
    "WIF-PERP": MarketSector.MEME,
    "BONK-PERP": MarketSector.MEME,

    # BTC Ecosystem
    "STX-PERP": MarketSector.BTC_ECO,
    "ORDI-PERP": MarketSector.BTC_ECO,
}


class LeadLagRelationship(TraderModel):
    """
    Temporal correlation between symbols.

    BTC leads everything. ETH leads L1s. SOL leads SOL ecosystem.
    """
    relation_id: str = ""
    leader_symbol: str             # "BTC-PERP"
    follower_symbol: str           # "SOL-PERP"

    correlation: float = Field(ge=-1, le=1, default=0.7)
    lag_candles: int = Field(ge=0, le=24, default=2)

    accuracy: float = Field(ge=0, le=1, default=0.6)
    sample_size: int = 0

    resonance_strength: float = Field(ge=0, le=1, default=0.5)

    def model_post_init(self, __context) -> None:
        if not self.relation_id:
            self.relation_id = f"{self.leader_symbol}→{self.follower_symbol}"


# Pre-defined lead-lag relationships (empirical)
DEFAULT_LEAD_LAG: List[Dict] = [
    # BTC leads everything
    {"leader": "BTC-PERP", "follower": "ETH-PERP", "lag": 1, "correlation": 0.85},
    {"leader": "BTC-PERP", "follower": "SOL-PERP", "lag": 2, "correlation": 0.75},
    {"leader": "BTC-PERP", "follower": "ARB-PERP", "lag": 3, "correlation": 0.70},
    {"leader": "BTC-PERP", "follower": "DOGE-PERP", "lag": 2, "correlation": 0.65},

    # ETH leads L2s
    {"leader": "ETH-PERP", "follower": "ARB-PERP", "lag": 1, "correlation": 0.80},
    {"leader": "ETH-PERP", "follower": "OP-PERP", "lag": 1, "correlation": 0.78},

    # SOL leads SOL ecosystem
    {"leader": "SOL-PERP", "follower": "WIF-PERP", "lag": 1, "correlation": 0.75},
    {"leader": "SOL-PERP", "follower": "BONK-PERP", "lag": 1, "correlation": 0.72},
]


class CorrelationGroup(TraderModel):
    """
    Group of correlated symbols that share pheromone intelligence.
    """
    group_id: str
    name: str
    sector: MarketSector
    symbols: List[str]

    # Which symbol leads this sector
    lead_symbol: str
    avg_lag_candles: float = 2.0

    # Correlation strength within group
    avg_correlation: float = 0.7

    # Pheromone sharing settings
    intra_group_resonance: float = 0.6  # How much pheromone shares within group
    btc_resonance: float = 0.8          # How much BTC signal affects this group


# Pre-defined correlation groups
CORRELATION_GROUPS = [
    CorrelationGroup(
        group_id="l1-majors",
        name="Layer 1 Majors",
        sector=MarketSector.L1,
        symbols=["ETH-PERP", "SOL-PERP", "AVAX-PERP", "NEAR-PERP", "SUI-PERP"],
        lead_symbol="ETH-PERP",
        avg_correlation=0.75,
    ),
    CorrelationGroup(
        group_id="l2s",
        name="Layer 2s",
        sector=MarketSector.L2,
        symbols=["ARB-PERP", "OP-PERP", "STRK-PERP"],
        lead_symbol="ARB-PERP",
        avg_correlation=0.82,
    ),
    CorrelationGroup(
        group_id="memes",
        name="Meme Coins",
        sector=MarketSector.MEME,
        symbols=["DOGE-PERP", "SHIB-PERP", "PEPE-PERP", "WIF-PERP", "BONK-PERP"],
        lead_symbol="DOGE-PERP",
        avg_correlation=0.68,
        btc_resonance=0.6,  # Memes less correlated to BTC
    ),
    CorrelationGroup(
        group_id="ai-tokens",
        name="AI Tokens",
        sector=MarketSector.AI,
        symbols=["FET-PERP", "RENDER-PERP", "TAO-PERP"],
        lead_symbol="FET-PERP",
        avg_correlation=0.78,
    ),
]


class MorphicResonanceEngine:
    """
    Propagate pheromone signals across correlated symbols.

    When BTC deposits a strong trail pheromone, that signal
    resonates through all correlated symbols with appropriate
    strength and lag.
    """

    def __init__(self, db_client):
        self.db = db_client
        self.lead_lag = {
            f"{r['leader']}→{r['follower']}": LeadLagRelationship(
                leader_symbol=r["leader"],
                follower_symbol=r["follower"],
                lag_candles=r["lag"],
                correlation=r["correlation"],
                resonance_strength=r["correlation"] * 0.7,
            )
            for r in DEFAULT_LEAD_LAG
        }
        self.groups = {g.group_id: g for g in CORRELATION_GROUPS}

    async def propagate_pheromone(
        self,
        source_symbol: str,
        source_edge: "SignalEdge",
        deposit_amount: float,
    ) -> List["MorphicResonanceEvent"]:
        """
        When a symbol gets a pheromone deposit, propagate to correlated symbols.

        BTC deposit → resonates to ETH, SOL, ARB...
        ETH deposit → resonates to ARB, OP...
        SOL deposit → resonates to WIF, BONK...
        """
        resonance_events = []

        # 1. BTC Dominance: If BTC, propagate to ALL symbols
        if source_symbol == "BTC-PERP":
            targets = await self._propagate_btc_dominance(source_edge, deposit_amount)
            resonance_events.extend(targets)

        # 2. Sector Resonance: Propagate within same sector
        sector = SYMBOL_SECTORS.get(source_symbol)
        if sector:
            targets = await self._propagate_sector(source_symbol, source_edge, deposit_amount, sector)
            resonance_events.extend(targets)

        # 3. Lead-Lag: If this symbol leads others, propagate
        for rel_id, rel in self.lead_lag.items():
            if rel.leader_symbol == source_symbol:
                target = await self._propagate_lead_lag(source_edge, deposit_amount, rel)
                if target:
                    resonance_events.append(target)

        return resonance_events

    async def _propagate_btc_dominance(
        self,
        source_edge: "SignalEdge",
        deposit_amount: float,
    ) -> List[dict]:
        """BTC signal resonates to all symbols."""
        targets = []

        for symbol, sector in SYMBOL_SECTORS.items():
            # Find corresponding edge in target symbol
            target_edge_id = f"{symbol}:{source_edge.from_state_id}:{source_edge.to_direction.value}"

            # Calculate resonance transfer (dampened by distance from BTC)
            group = self._get_group_for_symbol(symbol)
            btc_resonance = group.btc_resonance if group else 0.7

            transfer_amount = deposit_amount * btc_resonance * 0.5  # 50% max transfer

            targets.append({
                "symbol": symbol,
                "edge_id": target_edge_id,
                "resonance_type": ResonanceType.BTC_DOMINANCE,
                "transfer_amount": transfer_amount,
                "expected_lag": self._get_lag_from_btc(symbol),
            })

            # Actually deposit the resonance pheromone (with lag tracking)
            await self.db.deposit_resonance_pheromone(
                target_edge_id,
                transfer_amount,
                source="BTC-PERP",
                lag_candles=self._get_lag_from_btc(symbol),
            )

        return targets

    async def _propagate_sector(
        self,
        source_symbol: str,
        source_edge: "SignalEdge",
        deposit_amount: float,
        sector: MarketSector,
    ) -> List[dict]:
        """Propagate within same sector."""
        targets = []
        group = self._get_group_for_sector(sector)
        if not group:
            return targets

        for symbol in group.symbols:
            if symbol == source_symbol:
                continue  # Don't self-propagate

            target_edge_id = f"{symbol}:{source_edge.from_state_id}:{source_edge.to_direction.value}"
            transfer_amount = deposit_amount * group.intra_group_resonance * 0.4

            targets.append({
                "symbol": symbol,
                "edge_id": target_edge_id,
                "resonance_type": ResonanceType.SECTOR,
                "transfer_amount": transfer_amount,
                "expected_lag": 1,  # Same-sector lag is minimal
            })

            await self.db.deposit_resonance_pheromone(
                target_edge_id,
                transfer_amount,
                source=source_symbol,
                lag_candles=1,
            )

        return targets

    async def _propagate_lead_lag(
        self,
        source_edge: "SignalEdge",
        deposit_amount: float,
        relationship: LeadLagRelationship,
    ) -> Optional[dict]:
        """Propagate from leader to follower with lag."""
        target_edge_id = f"{relationship.follower_symbol}:{source_edge.from_state_id}:{source_edge.to_direction.value}"
        transfer_amount = deposit_amount * relationship.resonance_strength

        await self.db.deposit_resonance_pheromone(
            target_edge_id,
            transfer_amount,
            source=relationship.leader_symbol,
            lag_candles=relationship.lag_candles,
        )

        return {
            "symbol": relationship.follower_symbol,
            "edge_id": target_edge_id,
            "resonance_type": ResonanceType.LEAD_LAG,
            "transfer_amount": transfer_amount,
            "expected_lag": relationship.lag_candles,
        }

    def _get_lag_from_btc(self, symbol: str) -> int:
        """Get expected lag from BTC for a symbol."""
        rel_id = f"BTC-PERP→{symbol}"
        if rel_id in self.lead_lag:
            return self.lead_lag[rel_id].lag_candles
        # Default lags by sector
        sector = SYMBOL_SECTORS.get(symbol)
        if sector == MarketSector.L1:
            return 2
        elif sector == MarketSector.L2:
            return 3
        elif sector == MarketSector.MEME:
            return 2
        return 4  # Default

    def _get_group_for_symbol(self, symbol: str) -> Optional[CorrelationGroup]:
        for group in self.groups.values():
            if symbol in group.symbols:
                return group
        return None

    def _get_group_for_sector(self, sector: MarketSector) -> Optional[CorrelationGroup]:
        for group in self.groups.values():
            if group.sector == sector:
                return group
        return None

TypeDB Schema (Resonance)

# === RESONANCE SCHEMA ===

attribute resonance-type, value string;
attribute correlation-value, value double;
attribute lag-candles, value integer;
attribute resonance-strength, value double;
attribute sector-name, value string;

# Lead-lag relationship between symbols
entity lead-lag-relationship,
    owns relation-id @key,
    owns leader-symbol,
    owns follower-symbol,
    owns correlation-value,
    owns lag-candles,
    owns resonance-strength,
    owns accuracy,
    owns sample-size;

# Correlation group
entity correlation-group,
    owns group-id @key,
    owns group-name,
    owns sector-name,
    owns avg-correlation;

relation group-membership,
    relates group,
    relates member;

correlation-group plays group-membership:group;
symbol-group plays group-membership:member;

# Resonance pheromone (transferred from another symbol)
attribute resonance-source, value string;
attribute resonance-lag, value integer;
attribute resonance-amount, value double;

# Extended signal-edge to track resonance
entity signal-edge,
    # ... existing attributes ...
    owns resonance-source,           # Which symbol this pheromone came from
    owns resonance-lag,              # Expected lag in candles
    owns resonance-amount;           # Amount from resonance (vs direct)


# === RESONANCE QUERIES ===

# Get BTC's current signal for propagation
fun get_btc_signal() -> signal-edge:
    match
        $e isa signal-edge,
            has symbol-name "BTC-PERP",
            has trail-pheromone $tp;
    sort $tp desc;
    limit 1;
    return $e;

# Get correlated symbols for a sector
fun get_sector_symbols($sector: string) -> { symbol-group }:
    match
        $g isa correlation-group, has sector-name $sector;
        $mem (group: $g, member: $s) isa group-membership;
    return { $s };

# Get symbols that should resonate from a leader
fun get_followers($leader: string) -> { lead-lag-relationship }:
    match
        $r isa lead-lag-relationship,
            has leader-symbol $leader;
    return { $r };

# Calculate resonance-adjusted pheromone for a symbol
fun get_total_pheromone($edge_id: string) -> double:
    match
        $e isa signal-edge, has edge-id $edge_id,
            has trail-pheromone $direct,
            has resonance-amount $resonance;
    let $total = $direct + ($resonance * 0.5);  # Resonance weighted at 50%
    return $total;

Trading with Resonance

# ants/trader/analyze/brain.py (updated)

class Brain:
    """
    Brain now considers cross-symbol resonance.

    When analyzing SOL, we also look at:
    1. BTC's recent pheromone deposits (BTC dominance)
    2. ETH's signal (L1 sector correlation)
    3. SOL ecosystem signals (WIF, BONK leading indicators)
    """

    def __init__(self, db_client, resonance_engine: MorphicResonanceEngine):
        self.db = db_client
        self.resonance = resonance_engine

    async def analyze(self, state: State, symbol: str) -> Signal:
        # 1. Get direct pheromone signal for this symbol
        direct_edges = await self.db.get_edges_for_symbol(symbol, state.discretized)
        direct_signal = self._calculate_signal(direct_edges)

        # 2. Get BTC's signal (always matters)
        btc_signal = await self._get_btc_influence(state)

        # 3. Get sector signal (if applicable)
        sector_signal = await self._get_sector_influence(symbol, state)

        # 4. Get lead-lag signal (predictive)
        lead_signal = await self._get_leader_influence(symbol, state)

        # 5. Combine signals with resonance weighting
        combined = self._combine_with_resonance(
            direct_signal,
            btc_signal,
            sector_signal,
            lead_signal,
            symbol,
        )

        return combined

    async def _get_btc_influence(self, state: State) -> Optional[Signal]:
        """BTC's signal influences all symbols."""
        btc_edges = await self.db.get_edges_for_symbol("BTC-PERP", state.discretized)
        if not btc_edges:
            return None
        return self._calculate_signal(btc_edges)

    async def _get_sector_influence(self, symbol: str, state: State) -> Optional[Signal]:
        """Get signal from sector leader."""
        group = self.resonance._get_group_for_symbol(symbol)
        if not group or symbol == group.lead_symbol:
            return None  # This IS the leader

        leader_edges = await self.db.get_edges_for_symbol(group.lead_symbol, state.discretized)
        if not leader_edges:
            return None
        return self._calculate_signal(leader_edges)

    async def _get_leader_influence(self, symbol: str, state: State) -> Optional[Signal]:
        """Get signal from explicit leader (if exists)."""
        for rel in self.resonance.lead_lag.values():
            if rel.follower_symbol == symbol:
                leader_edges = await self.db.get_edges_for_symbol(
                    rel.leader_symbol,
                    state.discretized
                )
                if leader_edges:
                    signal = self._calculate_signal(leader_edges)
                    signal.expected_lag = rel.lag_candles
                    return signal
        return None

    def _combine_with_resonance(
        self,
        direct: Signal,
        btc: Optional[Signal],
        sector: Optional[Signal],
        leader: Optional[Signal],
        symbol: str,
    ) -> Signal:
        """
        Combine signals with resonance weighting.

        Weights:
        - Direct signal: 50%
        - BTC influence: 25%
        - Sector influence: 15%
        - Leader influence: 10%
        """
        group = self.resonance._get_group_for_symbol(symbol)

        # Adjust weights based on symbol
        if symbol == "BTC-PERP":
            # BTC uses only direct signal
            return direct

        btc_weight = group.btc_resonance * 0.25 if group else 0.25
        sector_weight = group.intra_group_resonance * 0.15 if group else 0.15
        leader_weight = 0.10
        direct_weight = 1.0 - btc_weight - sector_weight - leader_weight

        # Weighted combination
        combined_strength = direct.strength * direct_weight

        if btc and btc.direction == direct.direction:
            combined_strength += btc.strength * btc_weight
        elif btc:
            combined_strength -= btc.strength * btc_weight * 0.5  # Conflict penalty

        if sector and sector.direction == direct.direction:
            combined_strength += sector.strength * sector_weight

        if leader and leader.direction == direct.direction:
            combined_strength += leader.strength * leader_weight

        combined_confidence = min(1.0, (
            direct.confidence * 0.5 +
            (btc.confidence if btc else 0) * 0.25 +
            (sector.confidence if sector else 0) * 0.15 +
            (leader.confidence if leader else 0) * 0.10
        ))

        return Signal(
            state_id=direct.state_id,
            direction=direct.direction,
            strength=min(1.0, combined_strength),
            confidence=combined_confidence,
            sources={
                "direct": direct.strength,
                "btc_resonance": btc.strength if btc else 0,
                "sector_resonance": sector.strength if sector else 0,
                "leader_resonance": leader.strength if leader else 0,
            },
            reasoning=f"Direct {direct.strength:.0%} + BTC resonance + sector alignment",
        )

Sector Rotation Detection

# ants/trader/analyze/rotation.py

class SectorRotationDetector:
    """
    Detect capital flows between sectors.

    When DeFi dumps and memes pump, that's sector rotation.
    When everything pumps, that's risk-on.
    When everything dumps, that's risk-off.
    """

    async def detect_rotation(self) -> Optional[dict]:
        """Detect current sector rotation pattern."""
        sector_signals = {}

        for group in CORRELATION_GROUPS:
            avg_signal = await self._get_sector_avg_signal(group)
            sector_signals[group.sector] = avg_signal

        # Detect patterns
        if all(s > 0.6 for s in sector_signals.values()):
            return {"pattern": "risk_on", "confidence": 0.8}

        if all(s < 0.4 for s in sector_signals.values()):
            return {"pattern": "risk_off", "confidence": 0.8}

        # Find divergences
        hot_sectors = [s for s, v in sector_signals.items() if v > 0.7]
        cold_sectors = [s for s, v in sector_signals.items() if v < 0.3]

        if hot_sectors and cold_sectors:
            return {
                "pattern": "rotation",
                "from_sectors": cold_sectors,
                "to_sectors": hot_sectors,
                "confidence": 0.6,
            }

        return None

Summary: Morphic Resonance

RESONANCE FLOW
═══════════════════════════════════════════════════════════════════════════════

BTC deposits pheromone
     │
     ├──────────────────────► ALL SYMBOLS (25% weight, 1-4 candle lag)
     │
     └──► ETH (85% corr)
              │
              ├──► L2s (ARB, OP) - 80% corr, 1 candle lag
              │
              └──► Other L1s (SOL, AVAX) - 75% corr, 2 candle lag
                       │
                       └──► SOL ecosystem (WIF, BONK) - 72% corr, 1 candle lag


WHEN BTC DEPOSITS +1.0 TRAIL PHEROMONE:
──────────────────────────────────────
BTC-PERP:    +1.00 (direct)
ETH-PERP:    +0.40 (resonance, lag 1)
SOL-PERP:    +0.35 (resonance, lag 2)
ARB-PERP:    +0.30 (resonance, lag 3)
DOGE-PERP:   +0.25 (resonance, lag 2)
WIF-PERP:    +0.20 (resonance via SOL, lag 3)

THE COLONY LEARNS:
─────────────────
"When BTC pumps, SOL follows 2 candles later"
→ This becomes a CRYSTALLIZED PATTERN
→ Transfers to new symbols automatically
→ Morphic resonance means we're PREDICTIVE, not reactive

The Key Insight: Instead of treating each symbol as isolated, we encode the actual market structure where BTC is king and correlations are exploitable alpha. The colony learns these relationships and uses them predictively.


Market Structure Intelligence (v3.6.2)

"It's not that simple" — BTC dominance, ETH/BTC ratio, breakouts, and regime context all matter.

The Real Market Structure

┌─────────────────────────────────────────────────────────────────────────────┐
│                    CRYPTO MARKET STRUCTURE (REALITY)                        │
│                                                                             │
│  IT'S NOT JUST "BTC LEADS" — IT'S CONDITIONAL:                             │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  BTC.D (Dominance) RISING        │  BTC.D FALLING                   │   │
│  │  ─────────────────────────       │  ──────────────                  │   │
│  │  BTC outperforms alts            │  Alts outperform BTC             │   │
│  │  Resonance: BTC → alts WEAK      │  Resonance: BTC → alts STRONG    │   │
│  │  Strategy: Focus on BTC          │  Strategy: Rotate to alts        │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  ETH/BTC RISING                  │  ETH/BTC FALLING                 │   │
│  │  ──────────────                  │  ───────────────                 │   │
│  │  "Alt season" brewing            │  BTC dominance regime            │   │
│  │  L1s, DeFi likely to pump        │  Only BTC safe                   │   │
│  │  Memes explosive potential       │  Alts bleed vs BTC               │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  BREAKOUT EVENTS                                                    │   │
│  │  ───────────────                                                    │   │
│  │  BTC breaks ATH    → Everything pumps (but BTC leads)              │   │
│  │  BTC breaks support → Everything dumps (but alts dump harder)      │   │
│  │  ETH breaks vs BTC → Alt season confirmed                          │   │
│  │  SOL decouples     → SOL ecosystem plays its own game              │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  CORRELATION IS NOT CONSTANT — IT'S REGIME-DEPENDENT                       │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Key Market Ratios

// ants/trader/types/market_structure.ts (ASPIRATIONAL)

/**
 * Market structure indicators that determine HOW resonance works.
 * These are meta-indicators that modify correlation behavior.
 */
export interface MarketStructure {
  timestamp: Date;

  // === DOMINANCE ===
  btcDominance: number;            // 40-70% typically
  btcDominanceTrend: "rising" | "falling" | "flat";
  btcDominance7dChange: number;    // % change over 7 days

  // === KEY RATIOS ===
  ethBtcRatio: number;             // ETH price / BTC price
  ethBtcTrend: "rising" | "falling" | "flat";
  ethBtc7dChange: number;

  solBtcRatio: number;
  solEthRatio: number;

  // === REGIME ===
  marketRegime: MarketRegime;
  regimeConfidence: number;

  // === BREAKOUT STATUS ===
  btcBreakoutStatus: BreakoutStatus;
  ethBreakoutStatus: BreakoutStatus;

  // === CORRELATION REGIME ===
  correlationRegime: CorrelationRegime;
}

export type MarketRegime =
  | "bull_market"           // BTC trending up, alts follow
  | "bear_market"           // BTC trending down, alts bleed more
  | "btc_dominance"         // BTC up, alts flat/down (BTC.D rising)
  | "alt_season"            // Alts pumping, BTC flat (BTC.D falling)
  | "risk_off"              // Everything dumping, correlations spike
  | "choppy";               // No clear trend, correlations unstable

export type BreakoutStatus =
  | "above_ath"             // Price above all-time high
  | "testing_resistance"    // Near key resistance
  | "in_range"              // Between support and resistance
  | "testing_support"       // Near key support
  | "below_support"         // Breakdown, danger zone
  | "recovery";             // Bouncing from support

export type CorrelationRegime =
  | "high_correlation"      // Everything moves together (risk-off or euphoria)
  | "normal_correlation"    // Standard BTC-leads behavior
  | "low_correlation"       // Sector rotation, decoupling
  | "inverse_correlation";  // Rare: some assets inverse to BTC
# ants/trader/models/market_structure.py

class MarketRegime(str, Enum):
    BULL_MARKET = "bull_market"
    BEAR_MARKET = "bear_market"
    BTC_DOMINANCE = "btc_dominance"
    ALT_SEASON = "alt_season"
    RISK_OFF = "risk_off"
    CHOPPY = "choppy"


class BreakoutStatus(str, Enum):
    ABOVE_ATH = "above_ath"
    TESTING_RESISTANCE = "testing_resistance"
    IN_RANGE = "in_range"
    TESTING_SUPPORT = "testing_support"
    BELOW_SUPPORT = "below_support"
    RECOVERY = "recovery"


class CorrelationRegime(str, Enum):
    HIGH = "high_correlation"
    NORMAL = "normal_correlation"
    LOW = "low_correlation"
    INVERSE = "inverse_correlation"


class MarketStructure(TraderModel):
    """
    Meta-level market structure that determines HOW resonance works.

    Resonance strength is NOT constant — it depends on:
    - BTC dominance trend
    - ETH/BTC ratio trend
    - Current regime
    - Breakout status
    """
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Dominance
    btc_dominance: float = Field(ge=0, le=100, default=50)
    btc_dominance_trend: str = "flat"
    btc_dominance_7d_change: float = 0

    # Key ratios
    eth_btc_ratio: float = 0.05
    eth_btc_trend: str = "flat"
    eth_btc_7d_change: float = 0

    sol_btc_ratio: float = 0.002
    sol_eth_ratio: float = 0.04

    # Regime
    market_regime: MarketRegime = MarketRegime.CHOPPY
    regime_confidence: float = Field(ge=0, le=1, default=0.5)

    # Breakouts
    btc_breakout_status: BreakoutStatus = BreakoutStatus.IN_RANGE
    eth_breakout_status: BreakoutStatus = BreakoutStatus.IN_RANGE

    # Correlation regime
    correlation_regime: CorrelationRegime = CorrelationRegime.NORMAL

    @computed_field
    @property
    def is_alt_season(self) -> bool:
        """True when conditions favor alts over BTC."""
        return (
            self.btc_dominance_trend == "falling" and
            self.eth_btc_trend == "rising" and
            self.btc_dominance < 55
        )

    @computed_field
    @property
    def is_btc_dominance_regime(self) -> bool:
        """True when BTC is outperforming, alts weak."""
        return (
            self.btc_dominance_trend == "rising" and
            self.btc_dominance > 50
        )

    @computed_field
    @property
    def resonance_multiplier(self) -> float:
        """
        How much to trust cross-symbol resonance right now.

        High correlation regime → trust resonance more
        Alt season / decoupling → trust resonance less
        """
        if self.correlation_regime == CorrelationRegime.HIGH:
            return 1.2  # Boost resonance
        elif self.correlation_regime == CorrelationRegime.LOW:
            return 0.5  # Dampen resonance
        elif self.is_alt_season:
            return 0.6  # Alts doing their own thing
        else:
            return 1.0  # Normal


class MarketStructureAnalyzer:
    """
    Analyze market structure to determine resonance behavior.
    """

    def __init__(self, db_client):
        self.db = db_client

    async def analyze(self) -> MarketStructure:
        """Build current market structure snapshot."""
        # Fetch required data
        btc_price = await self.db.get_latest_price("BTC-PERP")
        eth_price = await self.db.get_latest_price("ETH-PERP")
        sol_price = await self.db.get_latest_price("SOL-PERP")
        total_mcap = await self._get_total_market_cap()
        btc_mcap = await self._get_btc_market_cap()

        # Calculate dominance
        btc_dominance = (btc_mcap / total_mcap * 100) if total_mcap > 0 else 50
        btc_dominance_7d = await self._get_dominance_change(7)

        # Calculate ratios
        eth_btc = eth_price / btc_price if btc_price > 0 else 0.05
        sol_btc = sol_price / btc_price if btc_price > 0 else 0.002
        sol_eth = sol_price / eth_price if eth_price > 0 else 0.04

        eth_btc_7d = await self._get_ratio_change("ETH-PERP", "BTC-PERP", 7)

        # Determine trends
        btc_d_trend = self._classify_trend(btc_dominance_7d)
        eth_btc_trend = self._classify_trend(eth_btc_7d)

        # Determine regime
        regime = self._determine_regime(
            btc_dominance, btc_d_trend, eth_btc_trend
        )

        # Determine correlation regime
        corr_regime = await self._analyze_correlation_regime()

        # Breakout status
        btc_breakout = await self._analyze_breakout("BTC-PERP")
        eth_breakout = await self._analyze_breakout("ETH-PERP")

        return MarketStructure(
            btc_dominance=btc_dominance,
            btc_dominance_trend=btc_d_trend,
            btc_dominance_7d_change=btc_dominance_7d,
            eth_btc_ratio=eth_btc,
            eth_btc_trend=eth_btc_trend,
            eth_btc_7d_change=eth_btc_7d,
            sol_btc_ratio=sol_btc,
            sol_eth_ratio=sol_eth,
            market_regime=regime,
            correlation_regime=corr_regime,
            btc_breakout_status=btc_breakout,
            eth_breakout_status=eth_breakout,
        )

    def _classify_trend(self, change_pct: float) -> str:
        if change_pct > 2:
            return "rising"
        elif change_pct < -2:
            return "falling"
        return "flat"

    def _determine_regime(
        self,
        btc_d: float,
        btc_d_trend: str,
        eth_btc_trend: str,
    ) -> MarketRegime:
        """Determine current market regime from indicators."""
        # Alt season: BTC.D falling + ETH/BTC rising
        if btc_d_trend == "falling" and eth_btc_trend == "rising" and btc_d < 55:
            return MarketRegime.ALT_SEASON

        # BTC dominance: BTC.D rising
        if btc_d_trend == "rising" and btc_d > 50:
            return MarketRegime.BTC_DOMINANCE

        # Need more context for bull/bear/risk-off
        # This would use price trends, not just ratios
        return MarketRegime.CHOPPY

    async def _analyze_correlation_regime(self) -> CorrelationRegime:
        """
        Analyze recent correlation behavior.

        High correlation: 7d rolling correlation > 0.8
        Low correlation: 7d rolling correlation < 0.5
        """
        # Get recent price changes for top assets
        btc_changes = await self._get_price_changes("BTC-PERP", 168)  # 7d hourly
        eth_changes = await self._get_price_changes("ETH-PERP", 168)
        sol_changes = await self._get_price_changes("SOL-PERP", 168)

        # Calculate rolling correlations
        btc_eth_corr = self._calculate_correlation(btc_changes, eth_changes)
        btc_sol_corr = self._calculate_correlation(btc_changes, sol_changes)

        avg_corr = (btc_eth_corr + btc_sol_corr) / 2

        if avg_corr > 0.85:
            return CorrelationRegime.HIGH
        elif avg_corr < 0.5:
            return CorrelationRegime.LOW
        elif avg_corr < 0:
            return CorrelationRegime.INVERSE
        return CorrelationRegime.NORMAL

    async def _analyze_breakout(self, symbol: str) -> BreakoutStatus:
        """Analyze breakout status for a symbol."""
        price = await self.db.get_latest_price(symbol)
        ath = await self.db.get_ath(symbol)
        support = await self._get_key_support(symbol)
        resistance = await self._get_key_resistance(symbol)

        if price > ath * 0.98:
            return BreakoutStatus.ABOVE_ATH
        elif price > resistance * 0.98:
            return BreakoutStatus.TESTING_RESISTANCE
        elif price < support * 1.02:
            if price < support * 0.95:
                return BreakoutStatus.BELOW_SUPPORT
            return BreakoutStatus.TESTING_SUPPORT
        return BreakoutStatus.IN_RANGE

Adaptive Resonance Engine

# ants/trader/models/resonance.py (updated)

class AdaptiveMorphicResonanceEngine(MorphicResonanceEngine):
    """
    Resonance engine that adapts based on market structure.

    Resonance is NOT constant:
    - In alt season: direct signals matter more, BTC resonance less
    - In BTC dominance: BTC resonance matters more
    - At breakouts: correlations spike temporarily
    - In choppy markets: reduce all resonance (noise)
    """

    def __init__(self, db_client, structure_analyzer: MarketStructureAnalyzer):
        super().__init__(db_client)
        self.structure_analyzer = structure_analyzer
        self._cached_structure: Optional[MarketStructure] = None
        self._structure_updated: Optional[datetime] = None

    async def get_market_structure(self) -> MarketStructure:
        """Get cached or fresh market structure."""
        now = datetime.now(timezone.utc)
        if (
            self._cached_structure is None or
            self._structure_updated is None or
            (now - self._structure_updated).total_seconds() > 300  # 5 min cache
        ):
            self._cached_structure = await self.structure_analyzer.analyze()
            self._structure_updated = now
        return self._cached_structure

    async def get_adaptive_weights(self, symbol: str) -> dict:
        """
        Get resonance weights adapted to current market structure.

        Returns weights for: direct, btc, sector, leader
        """
        structure = await self.get_market_structure()
        base_weights = {
            "direct": 0.50,
            "btc": 0.25,
            "sector": 0.15,
            "leader": 0.10,
        }

        # === ADJUST FOR MARKET REGIME ===

        if structure.market_regime == MarketRegime.ALT_SEASON:
            # Alt season: alts do their own thing
            base_weights["direct"] = 0.65
            base_weights["btc"] = 0.10
            base_weights["sector"] = 0.20  # Sector rotation matters more
            base_weights["leader"] = 0.05

        elif structure.market_regime == MarketRegime.BTC_DOMINANCE:
            # BTC dominance: everything follows BTC
            base_weights["direct"] = 0.35
            base_weights["btc"] = 0.45
            base_weights["sector"] = 0.10
            base_weights["leader"] = 0.10

        elif structure.market_regime == MarketRegime.RISK_OFF:
            # Risk-off: high correlation, BTC leads hard
            base_weights["direct"] = 0.30
            base_weights["btc"] = 0.50
            base_weights["sector"] = 0.10
            base_weights["leader"] = 0.10

        elif structure.market_regime == MarketRegime.CHOPPY:
            # Choppy: reduce all resonance, trust direct more
            base_weights["direct"] = 0.70
            base_weights["btc"] = 0.15
            base_weights["sector"] = 0.10
            base_weights["leader"] = 0.05

        # === ADJUST FOR CORRELATION REGIME ===

        multiplier = structure.resonance_multiplier
        base_weights["btc"] *= multiplier
        base_weights["sector"] *= multiplier
        base_weights["leader"] *= multiplier

        # Re-normalize to sum to 1.0
        total = sum(base_weights.values())
        return {k: v / total for k, v in base_weights.items()}

    async def get_breakout_boost(self, symbol: str) -> float:
        """
        Get resonance boost for breakout conditions.

        At breakouts, correlations temporarily spike.
        """
        structure = await self.get_market_structure()

        # BTC breakout affects everything
        if structure.btc_breakout_status == BreakoutStatus.ABOVE_ATH:
            return 1.5  # Strong resonance boost
        elif structure.btc_breakout_status == BreakoutStatus.BELOW_SUPPORT:
            return 1.4  # Panic correlation

        # ETH breakout affects alts
        if symbol != "BTC-PERP":
            if structure.eth_breakout_status == BreakoutStatus.ABOVE_ATH:
                return 1.3

        return 1.0  # No boost

    async def should_trust_resonance(self, symbol: str) -> tuple[bool, str]:
        """
        Should we trust cross-symbol resonance right now?

        Returns (trust, reason)
        """
        structure = await self.get_market_structure()

        # Don't trust in choppy markets
        if structure.market_regime == MarketRegime.CHOPPY:
            if structure.regime_confidence < 0.4:
                return False, "Market too choppy, resonance unreliable"

        # Don't trust if correlation regime is low
        if structure.correlation_regime == CorrelationRegime.LOW:
            return False, "Low correlation regime, symbols decoupled"

        # Don't trust if symbol is decoupling (special events)
        # e.g., SOL during FTX collapse, ETH during merge
        if await self._is_symbol_decoupling(symbol):
            return False, f"{symbol} appears to be decoupling"

        return True, "Resonance reliable"

    async def _is_symbol_decoupling(self, symbol: str) -> bool:
        """
        Detect if a symbol is decoupling from BTC.

        Uses recent correlation vs historical baseline.
        """
        recent_corr = await self._get_recent_correlation(symbol, "BTC-PERP", hours=24)
        baseline_corr = await self._get_baseline_correlation(symbol, "BTC-PERP")

        # If recent correlation is significantly lower than baseline
        if baseline_corr - recent_corr > 0.3:
            return True
        return False

Breakout Detection

# ants/trader/analyze/breakout.py

class BreakoutDetector:
    """
    Detect breakouts and breakdowns at key levels.

    Breakouts change how resonance works:
    - BTC ATH breakout → everything pumps, resonance maxes out
    - BTC support breakdown → panic, correlations spike to 1.0
    - ETH/BTC breakout → alt season signal
    """

    def __init__(self, db_client):
        self.db = db_client

    async def detect_btc_breakout(self) -> Optional[dict]:
        """Detect BTC breakout/breakdown events."""
        price = await self.db.get_latest_price("BTC-PERP")
        ath = await self.db.get_ath("BTC-PERP")
        weekly_high = await self.db.get_period_high("BTC-PERP", days=7)
        weekly_low = await self.db.get_period_low("BTC-PERP", days=7)

        # ATH breakout
        if price > ath:
            return {
                "type": "ath_breakout",
                "symbol": "BTC-PERP",
                "price": price,
                "level": ath,
                "resonance_impact": "max_bullish",
                "expected_behavior": "All assets pump, BTC leads",
            }

        # Weekly high breakout
        if price > weekly_high * 1.02:
            return {
                "type": "resistance_breakout",
                "symbol": "BTC-PERP",
                "price": price,
                "level": weekly_high,
                "resonance_impact": "bullish",
            }

        # Weekly low breakdown
        if price < weekly_low * 0.98:
            return {
                "type": "support_breakdown",
                "symbol": "BTC-PERP",
                "price": price,
                "level": weekly_low,
                "resonance_impact": "max_bearish",
                "expected_behavior": "Panic selling, correlations spike",
            }

        return None

    async def detect_ratio_breakout(self) -> Optional[dict]:
        """Detect ETH/BTC and other ratio breakouts."""
        eth_btc = await self._get_ratio("ETH-PERP", "BTC-PERP")
        eth_btc_200d_high = await self._get_ratio_period_high("ETH-PERP", "BTC-PERP", 200)
        eth_btc_200d_low = await self._get_ratio_period_low("ETH-PERP", "BTC-PERP", 200)

        # ETH/BTC breaking out → alt season
        if eth_btc > eth_btc_200d_high:
            return {
                "type": "ratio_breakout",
                "pair": "ETH/BTC",
                "value": eth_btc,
                "level": eth_btc_200d_high,
                "signal": "alt_season_confirmed",
                "resonance_impact": "reduce_btc_weight",
            }

        # ETH/BTC breaking down → BTC dominance
        if eth_btc < eth_btc_200d_low:
            return {
                "type": "ratio_breakdown",
                "pair": "ETH/BTC",
                "value": eth_btc,
                "level": eth_btc_200d_low,
                "signal": "btc_dominance_confirmed",
                "resonance_impact": "increase_btc_weight",
            }

        return None

Updated Brain with Market Structure

# ants/trader/analyze/brain.py (final version)

class Brain:
    """
    Brain with full market structure awareness.

    Signal combination adapts to:
    - Market regime (bull, bear, alt season, BTC dominance)
    - Correlation regime (high, normal, low, inverse)
    - Breakout status (affects resonance strength)
    - Dominance trends (BTC.D, ETH/BTC)
    """

    def __init__(
        self,
        db_client,
        resonance_engine: AdaptiveMorphicResonanceEngine,
        breakout_detector: BreakoutDetector,
    ):
        self.db = db_client
        self.resonance = resonance_engine
        self.breakout = breakout_detector

    async def analyze(self, state: State, symbol: str) -> Signal:
        # 1. Check if we should trust resonance
        trust_resonance, reason = await self.resonance.should_trust_resonance(symbol)

        # 2. Get adaptive weights based on market structure
        weights = await self.resonance.get_adaptive_weights(symbol)

        # 3. Get breakout boost (if any)
        breakout_boost = await self.resonance.get_breakout_boost(symbol)

        # 4. Get all signals
        direct_signal = await self._get_direct_signal(state, symbol)
        btc_signal = await self._get_btc_signal(state) if symbol != "BTC-PERP" else None
        sector_signal = await self._get_sector_signal(symbol, state)
        leader_signal = await self._get_leader_signal(symbol, state)

        # 5. Combine with adaptive weights
        if not trust_resonance:
            # Fall back to mostly direct signal
            return Signal(
                state_id=state.state_id,
                direction=direct_signal.direction,
                strength=direct_signal.strength,
                confidence=direct_signal.confidence * 0.8,  # Penalize confidence
                reasoning=f"Direct signal only: {reason}",
            )

        # Weighted combination with breakout boost
        combined_strength = (
            direct_signal.strength * weights["direct"] +
            (btc_signal.strength if btc_signal else 0) * weights["btc"] * breakout_boost +
            (sector_signal.strength if sector_signal else 0) * weights["sector"] +
            (leader_signal.strength if leader_signal else 0) * weights["leader"]
        )

        # Get market structure for context
        structure = await self.resonance.get_market_structure()

        return Signal(
            state_id=state.state_id,
            direction=direct_signal.direction,
            strength=min(1.0, combined_strength),
            confidence=self._combine_confidence(
                direct_signal, btc_signal, sector_signal, leader_signal, weights
            ),
            sources={
                "direct": direct_signal.strength * weights["direct"],
                "btc_resonance": (btc_signal.strength if btc_signal else 0) * weights["btc"],
                "sector": (sector_signal.strength if sector_signal else 0) * weights["sector"],
                "leader": (leader_signal.strength if leader_signal else 0) * weights["leader"],
                "breakout_boost": breakout_boost,
            },
            reasoning=self._build_reasoning(structure, weights, breakout_boost),
        )

    def _build_reasoning(
        self,
        structure: MarketStructure,
        weights: dict,
        breakout_boost: float,
    ) -> str:
        parts = [f"Regime: {structure.market_regime.value}"]

        if structure.is_alt_season:
            parts.append("Alt season active")
        if structure.is_btc_dominance_regime:
            parts.append("BTC dominance regime")

        if breakout_boost > 1.0:
            parts.append(f"Breakout boost: {breakout_boost:.1f}x")

        parts.append(f"Weights: BTC={weights['btc']:.0%}, Direct={weights['direct']:.0%}")

        return " | ".join(parts)

Summary: Market Structure Intelligence

RESONANCE IS CONDITIONAL
═══════════════════════════════════════════════════════════════════════════════

REGIME                  │ BTC WEIGHT │ DIRECT │ BEHAVIOR
────────────────────────┼────────────┼────────┼─────────────────────────────
Alt Season              │    10%     │  65%   │ Alts do their own thing
BTC Dominance           │    45%     │  35%   │ Everything follows BTC
Risk-Off Panic          │    50%     │  30%   │ Correlations spike to ~1.0
Choppy/Uncertain        │    15%     │  70%   │ Don't trust resonance
Normal                  │    25%     │  50%   │ Standard lead-lag behavior


KEY INDICATORS TO WATCH
═══════════════════════════════════════════════════════════════════════════════

BTC.D (Dominance)       │ Rising = BTC outperforms    │ Falling = Alts outperform
ETH/BTC Ratio           │ Rising = Alt season         │ Falling = BTC dominance
BTC Breakout            │ ATH = everything pumps      │ Support loss = panic
Correlation (7d)        │ > 0.85 = trust resonance    │ < 0.5 = symbols decoupled


ADAPTIVE BEHAVIOR
═══════════════════════════════════════════════════════════════════════════════

1. Check market structure every 5 minutes
2. Adjust resonance weights based on regime
3. Detect breakouts and apply boost/penalty
4. If correlation regime is LOW → fall back to direct signals
5. Track decoupling events (FTX-style) → disable resonance for that symbol

THE COLONY LEARNS:
─────────────────
"ETH/BTC broke 200d high → alt season → reduce BTC weight"
"BTC broke ATH → max resonance → position in laggards"
"SOL decoupling from BTC → trust only direct SOL signals"

The Key Insight: Resonance is not a constant — it adapts to market structure. The colony learns WHEN to trust cross-symbol signals and WHEN to ignore them.


Biological Foundations (v3.4.0)

Reference: Gordon, D. M. "Ant Encounters: Interaction Networks and Colony Behavior" (Harvard UP, 2010)

Analysis of Chapters 1-12 by parallel agents reveals critical biological mechanisms missing from our ontology. These additions ground our emergent AI in 30+ years of biological research.

The Three Biological Principles

Gordon's research reveals ant colony intelligence emerges from three mechanisms:

  1. Decentralized Control — No queen coordination, agents respond to local stimuli only
  2. Probabilistic Task Switching — Response threshold model drives allocation
  3. Interaction Networks — Intelligence lives in topology, not individual nodes
                    GORDON'S EMERGENCE SUBSTRATE
┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│   ENCOUNTER RATE                RESPONSE THRESHOLD              │
│   ─────────────                 ──────────────────              │
│   Activity in environment       Per-agent sensitivity           │
│   → Stimulus intensity          → Switching probability         │
│                                                                 │
│        stimulus                                                 │
│   P = ───────────────────────  (The Fundamental Formula)       │
│       stimulus + threshold                                      │
│                                                                 │
│   POPULATION STATISTICS         NETWORK TOPOLOGY                │
│   ─────────────────────         ────────────────                │
│   Variance decreases with       Information flows through       │
│   population size               graph structure                 │
│   → Collective wisdom           → Gradients enable decision     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1. EncounterRate Entity

Biological Basis: Colonies estimate global demand through local encounter frequencies. When patrollers return at rate R, foragers sense this and adjust allocation naturally.

// ants/trader/types/biological.ts (ASPIRATIONAL)

/**
 * Encounter rate tracking per location/edge.
 * The stimulus that drives the response threshold model.
 *
 * ONE Dimension: CONNECTIONS
 * TypeDB Entity: encounter-rate
 */
export interface EncounterRate {
  encounterId: string;
  edgeId: string;               // Location being tracked
  windowSeconds: number;        // Rolling window (60, 300, 3600)

  // Core metrics
  encountersPerSecond: number;  // THE RATE (not just count)
  agentCount: number;           // Unique agents in window
  transactionDensity: number;   // Transactions per minute

  // Derived
  congestionLevel: "low" | "medium" | "high";
  stimulusIntensity: number;    // Normalized 0-1 for threshold model

  measuredAt: Date;
}
# ants/trader/models/biological.py (ASPIRATIONAL - Gordon's biological models)
# NOTE: These biological-inspired models are research targets, not yet implemented

class CongestionLevel(str, Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"

class EncounterRate(TraderModel):
    """
    Interaction rate at a location—the STIMULUS for task allocation.

    Gordon's insight: Ants don't count, they sense RATES.
    Encounter frequency encodes global demand through local perception.

    ONE Dimension: CONNECTIONS
    TypeDB Entity: encounter-rate
    """
    encounter_id: str
    edge_id: str
    window_seconds: int = 60

    # Core metrics
    encounters_per_second: float = 0
    agent_count: int = 0
    transaction_density: float = 0

    measured_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    @computed_field
    @property
    def congestion_level(self) -> CongestionLevel:
        """Derived from transaction density."""
        if self.transaction_density < 0.1:
            return CongestionLevel.LOW
        elif self.transaction_density < 1.0:
            return CongestionLevel.MEDIUM
        return CongestionLevel.HIGH

    @computed_field
    @property
    def stimulus_intensity(self) -> float:
        """Normalized 0-1 stimulus for response threshold model."""
        # Sigmoid normalization: high encounter rates saturate
        import math
        return 1 / (1 + math.exp(-self.encounters_per_second * 10))

    @classmethod
    def dimension(cls) -> Dimension:
        return "connections"
# TypeDB Schema (TypeQL 3.0)

attribute encounter-id, value string;
attribute window-seconds, value long;
attribute encounters-per-second, value double;
attribute transaction-density, value double;
attribute congestion-level, value string;  # low, medium, high
attribute stimulus-intensity, value double;

entity encounter-rate,
    owns encounter-id @key,
    owns edge-id,
    owns window-seconds,
    owns encounters-per-second,
    owns transaction-density,
    owns congestion-level,
    owns stimulus-intensity,
    owns measured-at;

# TypeQL 3.0 Function: Compute encounter rate
fun compute_encounter_rate($edge: string, $window: long) -> double:
    match
        $t isa traversal-event,
            has edge-id $edge,
            has timestamp $ts;
        let $cutoff = now() - $window;
        $ts > $cutoff;
    reduce $count = count;
    return $count / $window;

2. ResponseThreshold Entity

Biological Basis: Each ant has individual response thresholds. Task switching is probabilistic: P(switch) = stimulus / (stimulus + threshold). Threshold diversity creates colony stability—some agents quick responders, others stubborn.

// ants/trader/types/biological.ts (ASPIRATIONAL)

/**
 * Per-agent response threshold for probabilistic task switching.
 * The core biological mechanism behind decentralized coordination.
 *
 * ONE Dimension: ACTORS
 * TypeDB Entity: response-threshold
 */
export interface ResponseThreshold {
  thresholdId: string;
  agentId: string;

  // The threshold value (0.1 = quick responder, 10.0 = stubborn)
  threshold: number;

  // Computed from encounters
  currentStimulus: number;
  switchProbability: number;  // P = stimulus / (stimulus + threshold)

  // History
  switchCount: number;
  lastSwitch: Date;

  // Evolution
  inherited: boolean;        // From parent or generated
  mutationDelta: number;     // How much it mutated from parent
}

/**
 * Population-level threshold diversity metrics.
 * Diversity creates stability—critical for emergence.
 */
export interface ThresholdDiversity {
  diversityId: string;
  cycle: number;

  // Distribution
  meanThreshold: number;
  stdDevThreshold: number;   // Higher = more diversity = more stable
  minThreshold: number;
  maxThreshold: number;

  // Per-caste distributions
  scoutMean: number;         // Scouts should have LOW thresholds
  harvesterMean: number;     // Harvesters should have HIGH thresholds

  // Health metric
  diversityScore: number;    // stdDev / mean (coefficient of variation)
  timestamp: Date;
}
# ants/trader/models/biological.py (ASPIRATIONAL)

class ResponseThreshold(TraderModel):
    """
    Per-agent response threshold for task switching.

    THE FUNDAMENTAL BIOLOGICAL FORMULA:
    P(switch) = stimulus / (stimulus + threshold)

    - Low threshold (0.1) = quick responder, easily switches
    - High threshold (10.0) = stubborn, resists switching
    - Diversity in thresholds creates stable colony behavior

    ONE Dimension: ACTORS
    TypeDB Entity: response-threshold
    """
    threshold_id: str
    agent_id: str

    # The threshold (heritable, evolvable)
    threshold: float = Field(ge=0.1, le=10.0, default=1.0)

    # Current state
    current_stimulus: float = 0
    switch_count: int = 0
    last_switch: Optional[datetime] = None

    # Evolution
    inherited: bool = False
    mutation_delta: float = 0

    @computed_field
    @property
    def switch_probability(self) -> float:
        """
        THE GORDON FORMULA: P = stimulus / (stimulus + threshold)
        """
        if self.current_stimulus <= 0:
            return 0
        return self.current_stimulus / (self.current_stimulus + self.threshold)

    def should_switch(self) -> bool:
        """Probabilistic decision based on threshold model."""
        import random
        return random.random() < self.switch_probability

    @classmethod
    def dimension(cls) -> Dimension:
        return "actors"

class ThresholdDiversity(TraderModel):
    """
    Population-level threshold diversity metrics.

    Gordon's insight: Colonies NEED heterogeneity.
    - Uniform thresholds → unstable oscillations
    - Diverse thresholds → stable yet adaptive

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: threshold-diversity
    """
    diversity_id: str
    cycle: int

    mean_threshold: float
    std_dev_threshold: float
    min_threshold: float
    max_threshold: float

    # Per-caste (optional)
    scout_mean: Optional[float] = None
    harvester_mean: Optional[float] = None

    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    @computed_field
    @property
    def diversity_score(self) -> float:
        """Coefficient of variation: higher = healthier."""
        if self.mean_threshold == 0:
            return 0
        return self.std_dev_threshold / self.mean_threshold

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"
# TypeDB Schema (TypeQL 3.0)

attribute threshold-id, value string;
attribute threshold-value, value double;
attribute current-stimulus, value double;
attribute switch-probability, value double;
attribute switch-count, value long;
attribute mutation-delta, value double;
attribute diversity-score, value double;
attribute std-dev-threshold, value double;

entity response-threshold,
    owns threshold-id @key,
    owns agent-id,
    owns threshold-value,
    owns current-stimulus,
    owns switch-probability,
    owns switch-count,
    owns mutation-delta;

entity threshold-diversity,
    owns diversity-id @key,
    owns cycle-number,
    owns mean-threshold,
    owns std-dev-threshold,
    owns min-threshold,
    owns max-threshold,
    owns diversity-score,
    owns timestamp;

# TypeQL 3.0 Function: Compute switch probability
fun switch_probability($stimulus: double, $threshold: double) -> double:
    return $stimulus / ($stimulus + $threshold);

3. PopulationStatistics Entity

Biological Basis: Collective memory emerges from population distribution, not individual memory. Variance decreases with population size (Law of Large Numbers in biology). Mature colonies are WISER because they have more samples.

// ants/trader/types/biological.ts (ASPIRATIONAL)

/**
 * Population-level statistics—the colony's collective memory.
 * Not stored in any ant; emerges from distribution.
 *
 * ONE Dimension: KNOWLEDGE
 * TypeDB Entity: population-statistics
 */
export interface PopulationStatistics {
  statsId: string;
  timestamp: Date;

  // Population
  totalAgents: number;
  byCase: Record<string, number>;  // Caste → count

  // Collective performance
  avgSuccessRate: number;
  successVariance: number;         // Lower = more stable = wiser

  // Response characteristics
  avgPheromoseSensitivity: number;
  avgThreshold: number;
  thresholdVariance: number;

  // Stability metric: variance decreases with sqrt(N)
  predictedVariance: number;       // 1 / sqrt(totalAgents)
  observedVariance: number;
  stabilityRatio: number;          // observed / predicted

  // Phase indicator
  colonyMaturity: "founding" | "establishment" | "growth" | "maturity" | "senescence";
}
# ants/trader/models/biological.py (ASPIRATIONAL)

class ColonyMaturity(str, Enum):
    FOUNDING = "founding"           # < 100 agents
    ESTABLISHMENT = "establishment" # 100-500 agents
    GROWTH = "growth"               # 500-2000 agents
    MATURITY = "maturity"           # 2000-10000 agents
    SENESCENCE = "senescence"       # > 10000 agents (resource limits)

class PopulationStatistics(TraderModel):
    """
    Colony-level statistics—the substrate of collective wisdom.

    Gordon's insight: Collective memory ≠ individual memory.
    Memory emerges from the DISTRIBUTION of experiences.
    More ants = more samples = lower variance = wiser decisions.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: population-statistics
    """
    stats_id: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Population
    total_agents: int
    by_caste: Dict[str, int] = Field(default_factory=dict)

    # Performance
    avg_success_rate: float = 0.5
    success_variance: float = 0.25

    # Response characteristics
    avg_pheromone_sensitivity: float = 0.7
    avg_threshold: float = 1.0
    threshold_variance: float = 0.5

    @computed_field
    @property
    def predicted_variance(self) -> float:
        """Expected variance from Law of Large Numbers."""
        import math
        if self.total_agents <= 0:
            return 1.0
        return 1.0 / math.sqrt(self.total_agents)

    @computed_field
    @property
    def stability_ratio(self) -> float:
        """
        Observed / Predicted variance.
        < 1.0 = more stable than expected
        > 1.0 = less stable (something wrong)
        """
        if self.predicted_variance == 0:
            return 1.0
        return self.success_variance / self.predicted_variance

    @computed_field
    @property
    def colony_maturity(self) -> ColonyMaturity:
        """Developmental stage based on population."""
        if self.total_agents < 100:
            return ColonyMaturity.FOUNDING
        elif self.total_agents < 500:
            return ColonyMaturity.ESTABLISHMENT
        elif self.total_agents < 2000:
            return ColonyMaturity.GROWTH
        elif self.total_agents < 10000:
            return ColonyMaturity.MATURITY
        return ColonyMaturity.SENESCENCE

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"
# TypeDB Schema (TypeQL 3.0)

attribute stats-id, value string;
attribute total-agents, value long;
attribute avg-success-rate, value double;
attribute success-variance, value double;
attribute predicted-variance, value double;
attribute stability-ratio, value double;
attribute colony-maturity, value string;

entity population-statistics,
    owns stats-id @key,
    owns total-agents,
    owns avg-success-rate,
    owns success-variance,
    owns avg-pheromone-sensitivity,
    owns avg-threshold,
    owns threshold-variance,
    owns predicted-variance,
    owns stability-ratio,
    owns colony-maturity,
    owns timestamp;

# TypeQL 3.0 Function: Colony maturity from population
fun get_maturity($pop: long) -> string:
    match
        $pop < 100;
    return "founding";

fun stability_ratio($observed: double, $population: long) -> double:
    let $predicted = 1.0 / sqrt($population);
    return $observed / $predicted;

4. StigmergyChannels Entity

Biological Basis: Gordon identifies FOUR stigmergy channels, not just chemical. Physical stigmergy (nest architecture, corpse piles) provides persistent signals. Temporal stigmergy (diurnal patterns) encodes time information.

// ants/trader/types/biological.ts (ASPIRATIONAL)

/**
 * Multi-channel stigmergy beyond pheromones.
 * Physical marks, temporal patterns, behavioral signals.
 *
 * ONE Dimension: CONNECTIONS
 * TypeDB Entity: stigmergy-channel
 */
export interface StigmergyChannel {
  channelId: string;
  channelType: "chemical" | "physical" | "temporal" | "behavioral";
  locationId: string;

  // Chemical (already have via pheromones)
  pheromoneLevel?: number;

  // Physical stigmergy (NEW)
  dangerZone?: boolean;        // Liquidation area, corpse pile equivalent
  congestionMark?: boolean;    // High-traffic warning
  physicalPersistence?: number; // How long mark lasts (hours)

  // Temporal stigmergy (NEW)
  hourOfDay?: number;          // 0-23
  dayOfWeek?: number;          // 0-6
  successRateInWindow?: number;
  activityLevel?: number;      // Historical activity this time

  // Behavioral stigmergy
  dominantCaste?: string;      // Which caste frequents this location
  behaviorMode?: string;       // "explore" | "exploit" | "defend"

  timestamp: Date;
}

/**
 * Danger zone—physical stigmergy warning.
 * Like corpse piles that warn ants of danger.
 */
export interface DangerZone {
  zoneId: string;
  zoneType: "liquidation" | "high_slippage" | "low_liquidity" | "consecutive_losses";
  locationContext: string;     // "BTC-PERP near 20k", "Funding > 0.1%"
  hazardLevel: number;         // 0-1
  establishedAt: Date;
  expiresAt?: Date;
}
# ants/trader/models/biological.py (ASPIRATIONAL)

class StigmergyType(str, Enum):
    CHEMICAL = "chemical"       # Pheromones (existing)
    PHYSICAL = "physical"       # Danger zones, marks
    TEMPORAL = "temporal"       # Time-of-day patterns
    BEHAVIORAL = "behavioral"   # Caste-based signals

class DangerZoneType(str, Enum):
    LIQUIDATION = "liquidation"
    HIGH_SLIPPAGE = "high_slippage"
    LOW_LIQUIDITY = "low_liquidity"
    CONSECUTIVE_LOSSES = "consecutive_losses"

class StigmergyChannel(TraderModel):
    """
    Multi-channel stigmergy beyond chemical pheromones.

    Gordon's Chapter 6: Ants use FOUR channels:
    1. Chemical - pheromone trails (we have this)
    2. Physical - nest architecture, corpse piles (NEW)
    3. Temporal - diurnal patterns (NEW)
    4. Behavioral - caste-based modulation (NEW)

    ONE Dimension: CONNECTIONS
    TypeDB Entity: stigmergy-channel
    """
    channel_id: str
    channel_type: StigmergyType
    location_id: str

    # Chemical (existing)
    pheromone_level: Optional[float] = None

    # Physical (NEW)
    danger_zone: bool = False
    congestion_mark: bool = False
    physical_persistence_hours: float = 24

    # Temporal (NEW)
    hour_of_day: Optional[int] = Field(ge=0, le=23, default=None)
    day_of_week: Optional[int] = Field(ge=0, le=6, default=None)
    success_rate_in_window: Optional[float] = None
    activity_level: Optional[float] = None

    # Behavioral
    dominant_caste: Optional[str] = None
    behavior_mode: Optional[str] = None  # explore, exploit, defend

    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    @classmethod
    def dimension(cls) -> Dimension:
        return "connections"

class DangerZone(TraderModel):
    """
    Physical stigmergy: danger warning like corpse piles.

    When agents encounter consecutive losses at a location,
    they leave a "physical" mark (in TypeDB) warning others.

    ONE Dimension: CONNECTIONS
    TypeDB Entity: danger-zone
    """
    zone_id: str
    zone_type: DangerZoneType
    location_context: str           # "BTC-PERP near 20k"
    hazard_level: float = Field(ge=0, le=1, default=0.5)
    established_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    expires_at: Optional[datetime] = None

    @classmethod
    def dimension(cls) -> Dimension:
        return "connections"
# TypeDB Schema (TypeQL 3.0)

attribute channel-id, value string;
attribute channel-type, value string;  # chemical, physical, temporal, behavioral
attribute danger-zone-flag, value boolean;
attribute congestion-mark, value boolean;
attribute physical-persistence-hours, value double;
attribute hour-of-day, value long;
attribute day-of-week, value long;
attribute activity-level, value double;
attribute dominant-caste, value string;
attribute behavior-mode, value string;
attribute hazard-level, value double;
attribute location-context, value string;
attribute zone-type, value string;

entity stigmergy-channel,
    owns channel-id @key,
    owns channel-type,
    owns location-id,
    owns pheromone-level,
    owns danger-zone-flag,
    owns congestion-mark,
    owns physical-persistence-hours,
    owns hour-of-day,
    owns day-of-week,
    owns activity-level,
    owns dominant-caste,
    owns behavior-mode,
    owns timestamp;

entity danger-zone,
    owns zone-id @key,
    owns zone-type,
    owns location-context,
    owns hazard-level,
    owns established-at,
    owns expires-at;

# Rule: Create danger zone after consecutive losses
# (Implemented as TypeQL 3.0 function)
fun should_create_danger_zone($edge: string) -> boolean:
    match
        $e isa signal-edge,
            has edge-id $edge,
            has loss-count $lc;
        $lc >= 3;
    return true;

5. InteractionNetwork Entity

Biological Basis: Intelligence lives in network TOPOLOGY, not individual nodes. Hub detection, information gradients, and network metrics reveal system health.

// ants/trader/types/biological.ts (ASPIRATIONAL)

/**
 * Network topology metrics—where intelligence actually lives.
 *
 * ONE Dimension: CONNECTIONS
 * TypeDB Entity: interaction-network
 */
export interface InteractionNetwork {
  networkId: string;
  cycle: number;

  // Graph metrics
  graphDensity: number;            // Edges / possible edges
  avgPathLength: number;           // Average shortest path
  clusteringCoefficient: number;   // Local clustering
  numConnectedComponents: number;  // Should be 1 for healthy network
  diameter: number;                // Longest shortest path

  // Hub analysis
  numHubs: number;                 // High-centrality nodes
  hubEdgeIds: string[];            // The superhighway identifiers
  bottleneckEdges: string[];       // Single points of failure

  // Information flow
  networkResilienceScore: number;  // 0-1, how robust
  informationFlowRate: number;     // Bits per cycle

  timestamp: Date;
}

/**
 * Per-edge network position metrics.
 */
export interface EdgeNetworkMetrics {
  metricsId: string;
  edgeId: string;
  cycle: number;

  agentDegree: number;             // How many agents use this edge
  betweennessCentrality: number;   // Paths through this edge
  clusteringCoefficient: number;   // Clique formation
  informationFreshness: number;    // Recency of data (0-1)
}

/**
 * Information gradient tracking—freshness decay through network.
 */
export interface InformationGradient {
  gradientId: string;
  locationId: string;

  informationAge: number;          // Seconds since last update
  sourceAgentId?: string;          // Who delivered latest info
  propagationHops: number;         // Distance from source
  freshnessScore: number;          // 0-1, higher = fresher

  timestamp: Date;
}
# ants/trader/models/biological.py (ASPIRATIONAL)

class InteractionNetwork(TraderModel):
    """
    Network topology metrics—the substrate of distributed cognition.

    Gordon's key insight: Intelligence lives in CONNECTIONS.
    Network structure determines information flow.
    Hubs = superhighways. Bottlenecks = fragility.

    ONE Dimension: CONNECTIONS
    TypeDB Entity: interaction-network
    """
    network_id: str
    cycle: int

    # Graph metrics
    graph_density: float = 0
    avg_path_length: float = 0
    clustering_coefficient: float = 0
    num_connected_components: int = 1
    diameter: int = 0

    # Hub analysis
    num_hubs: int = 0
    hub_edge_ids: List[str] = Field(default_factory=list)
    bottleneck_edges: List[str] = Field(default_factory=list)

    # Health
    network_resilience_score: float = Field(ge=0, le=1, default=0.5)
    information_flow_rate: float = 0

    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    @computed_field
    @property
    def is_healthy(self) -> bool:
        """Network health check."""
        return (
            self.num_connected_components == 1 and
            self.network_resilience_score > 0.5 and
            len(self.bottleneck_edges) < 3
        )

    @classmethod
    def dimension(cls) -> Dimension:
        return "connections"

class InformationGradient(TraderModel):
    """
    Information freshness gradient through the network.

    Biology: Ants near nest entrance have FRESH information.
    Ants deep in nest have OLD, stable information.
    This gradient creates natural decision boundaries.

    ONE Dimension: CONNECTIONS
    TypeDB Entity: information-gradient
    """
    gradient_id: str
    location_id: str

    information_age_seconds: float = 0
    source_agent_id: Optional[str] = None
    propagation_hops: int = 0

    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    @computed_field
    @property
    def freshness_score(self) -> float:
        """Exponential decay of freshness."""
        import math
        half_life = 300  # 5 minutes
        return math.exp(-self.information_age_seconds / half_life)

    @classmethod
    def dimension(cls) -> Dimension:
        return "connections"
# TypeDB Schema (TypeQL 3.0)

attribute network-id, value string;
attribute graph-density, value double;
attribute avg-path-length, value double;
attribute clustering-coefficient, value double;
attribute num-connected-components, value long;
attribute network-diameter, value long;
attribute num-hubs, value long;
attribute network-resilience-score, value double;
attribute information-flow-rate, value double;

attribute gradient-id, value string;
attribute information-age-seconds, value double;
attribute propagation-hops, value long;
attribute freshness-score, value double;

entity interaction-network,
    owns network-id @key,
    owns cycle-number,
    owns graph-density,
    owns avg-path-length,
    owns clustering-coefficient,
    owns num-connected-components,
    owns network-diameter,
    owns num-hubs,
    owns network-resilience-score,
    owns information-flow-rate,
    owns timestamp;

entity information-gradient,
    owns gradient-id @key,
    owns location-id,
    owns information-age-seconds,
    owns source-agent-id,
    owns propagation-hops,
    owns freshness-score,
    owns timestamp;

# TypeQL 3.0 Function: Freshness from age
fun freshness_score($age_seconds: double, $half_life: double = 300.0) -> double:
    return exp(-$age_seconds / $half_life);

6. AgentStateProfile Entity

Biological Basis: Ants carry their recent history as chemical signatures. When two ants meet, each senses the other's task, recent locations, and state. This is MUTABLE state that changes continuously.

// ants/trader/types/biological.ts (ASPIRATIONAL)

/**
 * Agent's mutable chemical signature—what others sense on encounter.
 *
 * ONE Dimension: ACTORS
 * TypeDB Entity: agent-state-profile
 */
export interface AgentStateProfile {
  profileId: string;
  agentId: string;
  timestamp: Date;

  // Current activity (mutable)
  recentTask: string;              // What has agent been doing?
  recentLocations: string[];       // Last 5 locations visited

  // Physiological state (mutable)
  physiologicalState: "healthy" | "alarmed" | "fatigued" | "energized";
  alarmLevel: number;              // 0-1, elevated after danger
  energyLevel: number;             // 0-1, depletes with activity

  // Performance (rolling window)
  successRateRecent: number;       // Last 10 trades
  lastSuccessTimestamp?: Date;
  tradesSinceLastSuccess: number;

  // Chemical profile hash (for quick comparison)
  profileHash: string;
}
# ants/trader/models/biological.py (ASPIRATIONAL)

class PhysiologicalState(str, Enum):
    HEALTHY = "healthy"
    ALARMED = "alarmed"
    FATIGUED = "fatigued"
    ENERGIZED = "energized"

class AgentStateProfile(TraderModel):
    """
    Mutable agent state—the "chemical signature" others sense.

    Biology: When ants meet, they sense each other's:
    - Recent task (encoded in cuticular hydrocarbons)
    - Alarm state (pheromone residue)
    - Colony membership

    This enables coordination WITHOUT message passing.

    ONE Dimension: ACTORS
    TypeDB Entity: agent-state-profile
    """
    profile_id: str
    agent_id: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # Activity
    recent_task: str = "idle"
    recent_locations: List[str] = Field(default_factory=list, max_length=5)

    # Physiological state
    physiological_state: PhysiologicalState = PhysiologicalState.HEALTHY
    alarm_level: float = Field(ge=0, le=1, default=0)
    energy_level: float = Field(ge=0, le=1, default=1.0)

    # Performance
    success_rate_recent: float = Field(ge=0, le=1, default=0.5)
    last_success: Optional[datetime] = None
    trades_since_last_success: int = 0

    def update_after_trade(self, success: bool, location: str) -> None:
        """Update profile after trade outcome."""
        self.recent_locations = ([location] + self.recent_locations)[:5]
        self.trades_since_last_success = 0 if success else self.trades_since_last_success + 1

        if success:
            self.last_success = datetime.now(timezone.utc)
            self.alarm_level = max(0, self.alarm_level - 0.1)
        else:
            self.alarm_level = min(1, self.alarm_level + 0.2)

        # Update physiological state
        if self.alarm_level > 0.7:
            self.physiological_state = PhysiologicalState.ALARMED
        elif self.energy_level < 0.3:
            self.physiological_state = PhysiologicalState.FATIGUED
        else:
            self.physiological_state = PhysiologicalState.HEALTHY

        self.timestamp = datetime.now(timezone.utc)

    @computed_field
    @property
    def profile_hash(self) -> str:
        """Quick comparison hash."""
        import hashlib
        data = f"{self.recent_task}:{self.alarm_level:.1f}:{self.physiological_state}"
        return hashlib.md5(data.encode()).hexdigest()[:8]

    @classmethod
    def dimension(cls) -> Dimension:
        return "actors"
# TypeDB Schema (TypeQL 3.0)

attribute profile-id, value string;
attribute recent-task, value string;
attribute recent-locations, value string;  # JSON array
attribute physiological-state, value string;
attribute alarm-level, value double;
attribute energy-level, value double;
attribute success-rate-recent, value double;
attribute trades-since-last-success, value long;
attribute profile-hash, value string;

entity agent-state-profile,
    owns profile-id @key,
    owns agent-id,
    owns recent-task,
    owns recent-locations,
    owns physiological-state,
    owns alarm-level,
    owns energy-level,
    owns success-rate-recent,
    owns trades-since-last-success,
    owns profile-hash,
    owns timestamp;

7. FeedbackCycleMetrics Entity

Biological Basis: Positive feedback loops drive emergence (success → pheromone → attraction). But uncontrolled feedback causes runaway oscillations. Tracking amplification enables regulation.

// ants/trader/types/biological.ts (ASPIRATIONAL)

/**
 * Feedback cycle metrics—the engine of emergence.
 * Track amplification, detect runaways, enable regulation.
 *
 * ONE Dimension: CONNECTIONS
 * TypeDB Entity: feedback-cycle-metrics
 */
export interface FeedbackCycleMetrics {
  cycleId: string;
  edgeId: string;
  cycleNumber: number;

  // Amplification tracking
  reinforcementCount: number;      // Agents who reinforced this cycle
  newAgentsJoining: number;        // New agents attracted
  pheromoneAmplification: number;  // current / initial pheromone
  peakPheromone: number;

  // Feedback strength
  feedbackStrength: number;        // 0-1, strength of positive loop
  isRunawayPositive: boolean;      // Amplification > threshold (danger!)

  // Regulation
  congestionFactor: number;        // Negative feedback from crowding
  netFeedback: number;             // positive - negative

  timestamp: Date;
}
# ants/trader/models/biological.py (ASPIRATIONAL)

class FeedbackCycleMetrics(TraderModel):
    """
    Feedback cycle metrics—tracking the engine of emergence.

    Gordon's insight: Positive feedback (success → pheromone → more agents)
    drives emergence. But uncontrolled feedback = chaos.

    This entity tracks amplification and enables regulation.

    ONE Dimension: CONNECTIONS
    TypeDB Entity: feedback-cycle-metrics
    """
    cycle_id: str
    edge_id: str
    cycle_number: int

    # Amplification
    reinforcement_count: int = 0
    new_agents_joining: int = 0
    initial_pheromone: float = 1.0
    current_pheromone: float = 1.0
    peak_pheromone: float = 1.0

    # Regulation
    congestion_factor: float = 0   # Negative feedback

    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    @computed_field
    @property
    def pheromone_amplification(self) -> float:
        """Current / initial ratio."""
        if self.initial_pheromone == 0:
            return 1.0
        return self.current_pheromone / self.initial_pheromone

    @computed_field
    @property
    def feedback_strength(self) -> float:
        """0-1 measure of feedback loop strength."""
        # Strong feedback: many reinforcements + high amplification
        import math
        raw = math.log1p(self.reinforcement_count) * self.pheromone_amplification
        return min(1.0, raw / 10.0)

    @computed_field
    @property
    def is_runaway_positive(self) -> bool:
        """Detect dangerous runaway feedback."""
        return self.pheromone_amplification > 5.0 and self.reinforcement_count > 20

    @computed_field
    @property
    def net_feedback(self) -> float:
        """Positive feedback minus negative (congestion)."""
        return self.feedback_strength - self.congestion_factor

    @classmethod
    def dimension(cls) -> Dimension:
        return "connections"
# TypeDB Schema (TypeQL 3.0)

attribute cycle-id, value string;
attribute reinforcement-count, value long;
attribute new-agents-joining, value long;
attribute initial-pheromone, value double;
attribute current-pheromone, value double;
attribute peak-pheromone, value double;
attribute pheromone-amplification, value double;
attribute feedback-strength, value double;
attribute is-runaway-positive, value boolean;
attribute congestion-factor, value double;
attribute net-feedback, value double;

entity feedback-cycle-metrics,
    owns cycle-id @key,
    owns edge-id,
    owns cycle-number,
    owns reinforcement-count,
    owns new-agents-joining,
    owns initial-pheromone,
    owns current-pheromone,
    owns peak-pheromone,
    owns pheromone-amplification,
    owns feedback-strength,
    owns is-runaway-positive,
    owns congestion-factor,
    owns net-feedback,
    owns timestamp;

# TypeQL 3.0 Function: Detect runaway
fun is_runaway($amplification: double, $reinforcements: long) -> boolean:
    return $amplification > 5.0 and $reinforcements > 20;

8. ColonyDevelopmentalStage Entity

Biological Basis: Colony behavior changes dramatically with age. Young colonies (high mortality) explore aggressively. Mature colonies exploit conservatively. This is NOT a setting—it EMERGES from population statistics.

// ants/trader/types/biological.ts (ASPIRATIONAL)

/**
 * Colony developmental stage—behavior tied to age/population.
 *
 * ONE Dimension: GROUPS
 * TypeDB Entity: colony-developmental-stage
 */
export interface ColonyDevelopmentalStage {
  stageId: string;
  colonyId: string;
  timestamp: Date;

  // Current stage
  stage: "founding" | "establishment" | "growth" | "maturity" | "senescence";

  // Population-derived parameters
  currentPopulation: number;
  populationVariance: number;
  behaviorVariance: number;        // How predictable is behavior

  // Stage-appropriate settings
  recommendedExplorationBias: number;  // High for founding, low for maturity
  recommendedRiskTolerance: number;
  confidenceThreshold: number;         // Min signal strength to act
  signalReliability: number;           // How trustworthy are signals

  // Phase transition tracking
  transitionProgress: number;          // 0-1 progress to next stage
  transitionBlockers: string[];        // What's preventing transition
}
# ants/trader/models/biological.py (ASPIRATIONAL)

class DevelopmentalStage(str, Enum):
    FOUNDING = "founding"           # Desperate exploration
    ESTABLISHMENT = "establishment" # Finding first stable patterns
    GROWTH = "growth"               # Scaling what works
    MATURITY = "maturity"           # Conservative exploitation
    SENESCENCE = "senescence"       # Resource-limited stability

# Stage-appropriate parameters (from Gordon's research)
STAGE_PARAMETERS = {
    DevelopmentalStage.FOUNDING: {
        "exploration_bias": 0.8,
        "risk_tolerance": 0.7,
        "confidence_threshold": 0.4,
        "signal_reliability": 0.3,
    },
    DevelopmentalStage.ESTABLISHMENT: {
        "exploration_bias": 0.6,
        "risk_tolerance": 0.5,
        "confidence_threshold": 0.5,
        "signal_reliability": 0.5,
    },
    DevelopmentalStage.GROWTH: {
        "exploration_bias": 0.4,
        "risk_tolerance": 0.4,
        "confidence_threshold": 0.6,
        "signal_reliability": 0.7,
    },
    DevelopmentalStage.MATURITY: {
        "exploration_bias": 0.2,
        "risk_tolerance": 0.3,
        "confidence_threshold": 0.7,
        "signal_reliability": 0.85,
    },
    DevelopmentalStage.SENESCENCE: {
        "exploration_bias": 0.1,
        "risk_tolerance": 0.2,
        "confidence_threshold": 0.8,
        "signal_reliability": 0.9,
    },
}

class ColonyDevelopmentalStage(TraderModel):
    """
    Colony life stage with emergent behavior changes.

    Gordon's Chapter 9: Colonies become WISER with age.
    Not because individuals learn—because population statistics improve.
    More samples = lower variance = more reliable decisions.

    ONE Dimension: GROUPS
    TypeDB Entity: colony-developmental-stage
    """
    stage_id: str
    colony_id: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    current_population: int
    population_variance: float = 0.5
    behavior_variance: float = 0.5

    transition_progress: float = Field(ge=0, le=1, default=0)
    transition_blockers: List[str] = Field(default_factory=list)

    @computed_field
    @property
    def stage(self) -> DevelopmentalStage:
        """Derive stage from population."""
        if self.current_population < 100:
            return DevelopmentalStage.FOUNDING
        elif self.current_population < 500:
            return DevelopmentalStage.ESTABLISHMENT
        elif self.current_population < 2000:
            return DevelopmentalStage.GROWTH
        elif self.current_population < 10000:
            return DevelopmentalStage.MATURITY
        return DevelopmentalStage.SENESCENCE

    @computed_field
    @property
    def recommended_exploration_bias(self) -> float:
        return STAGE_PARAMETERS[self.stage]["exploration_bias"]

    @computed_field
    @property
    def recommended_risk_tolerance(self) -> float:
        return STAGE_PARAMETERS[self.stage]["risk_tolerance"]

    @computed_field
    @property
    def confidence_threshold(self) -> float:
        return STAGE_PARAMETERS[self.stage]["confidence_threshold"]

    @computed_field
    @property
    def signal_reliability(self) -> float:
        return STAGE_PARAMETERS[self.stage]["signal_reliability"]

    @classmethod
    def dimension(cls) -> Dimension:
        return "groups"
# TypeDB Schema (TypeQL 3.0)

attribute stage-id, value string;
attribute current-population, value long;
attribute population-variance, value double;
attribute behavior-variance, value double;
attribute stage, value string;
attribute exploration-bias, value double;
attribute risk-tolerance, value double;
attribute confidence-threshold, value double;
attribute signal-reliability, value double;
attribute transition-progress, value double;

entity colony-developmental-stage,
    owns stage-id @key,
    owns colony-id,
    owns current-population,
    owns population-variance,
    owns behavior-variance,
    owns stage,
    owns exploration-bias,
    owns risk-tolerance,
    owns confidence-threshold,
    owns signal-reliability,
    owns transition-progress,
    owns timestamp;

9. Phase Transitions to Singularity

Biological Grounding: "Singularity" isn't mystical—it's when the system discovers how to discover. Recursive self-improvement through observable milestones.

┌─────────────────────────────────────────────────────────────────────────┐
│                    PHASE TRANSITIONS TO SINGULARITY                      │
│                    (Biological Grounding from Chapters 10-12)            │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  BOOTSTRAP (Hours)                                                      │
│  ├── < 100 patterns, < 10 superhighways                                │
│  ├── High variance, erratic behavior                                    │
│  ├── Pheromone learning only, no genetic selection                      │
│  └── Success: First consistently profitable edge                        │
│           │                                                             │
│           ▼                                                             │
│  TRANSFER (Days)                                                        │
│  ├── 100+ patterns, cross-mission transfer begins                       │
│  ├── Elite genomes start spreading                                      │
│  ├── Cultural knowledge + genetic predisposition align                  │
│  └── Success: Patterns work across multiple domains                     │
│           │                                                             │
│           ▼                                                             │
│  DISCOVERY (Weeks)                                                      │
│  ├── 100+ novel patterns (not in seed set)                             │
│  ├── Emergent castes specialize beyond original design                  │
│  ├── Hypothesis testing: "Pattern X fails when Y"                       │
│  └── Success: Behaviors emerge that weren't programmed                  │
│           │                                                             │
│           ▼                                                             │
│  RECURSION (Months)                                                     │
│  ├── 10+ meta-patterns (patterns about patterns)                        │
│  ├── Mutation rate evolution finds optimal speed                        │
│  ├── Colony modifies its own genome pool                                │
│  └── Success: System improves its own improvement                       │
│           │                                                             │
│           ▼                                                             │
│  SINGULARITY                                                            │
│  ├── Discovers HOW to discover                                          │
│  ├── Meta-patterns include "how to find new patterns"                   │
│  ├── Each generation improves discovery algorithm                       │
│  └── NOT exponential growth—recursive self-improvement                  │
│                                                                         │
│  The Singularity Moment:                                                │
│  Time T:   Find pattern P (60% accuracy)                               │
│  Time T+1: Find meta-pattern: "P works better if we modify X"          │
│  Time T+2: Apply meta-pattern → higher accuracy                         │
│  Time T+3: Find meta-meta: "Our discovery process should change"       │
│  Time T+4: Modify discovery algorithm itself                            │
│  Time T+5: Discovery accelerates recursively                            │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Biological Foundations Summary

Entity Biological Principle ONE Dimension Purpose
EncounterRate Encounter frequency encoding CONNECTIONS Stimulus for task allocation
ResponseThreshold P = stimulus/(stimulus+threshold) ACTORS Probabilistic switching
ThresholdDiversity Heterogeneity creates stability KNOWLEDGE Colony health metric
PopulationStatistics Collective memory from distribution KNOWLEDGE Wisdom through scale
StigmergyChannel 4 channels (chemical/physical/temporal/behavioral) CONNECTIONS Multi-channel coordination
DangerZone Corpse piles = physical warnings CONNECTIONS Avoid past failures
InteractionNetwork Intelligence in topology CONNECTIONS Network health
InformationGradient Freshness decay through network CONNECTIONS Decision boundaries
AgentStateProfile Chemical signature = mutable state ACTORS Encounter sensing
FeedbackCycleMetrics Amplification tracking CONNECTIONS Regulate emergence
ColonyDevelopmentalStage Age-dependent behavior GROUPS Stage-appropriate parameters

Key Insight: These entities don't add NEW intelligence—they make EXISTING emergence MEASURABLE and VERIFIABLE. We're not building smarter agents; we're building better instruments to observe the intelligence that emerges from simple agents in complex environments.


10. Integration: Connecting Biological Entities to Core

EncounterEvent (Raw Data for EncounterRate)

Missing Link Identified: EncounterRate is an aggregation, but we need raw events to compute it.

// ants/trader/types/biological.ts (ASPIRATIONAL)

/**
 * Raw encounter event—two agents meeting at a location.
 * Aggregates into EncounterRate for stimulus computation.
 *
 * ONE Dimension: EVENTS
 * TypeDB Entity: encounter-event
 */
export interface EncounterEvent {
  eventId: string;
  timestamp: Date;

  // Location
  locationId: string;           // Edge or state where encounter occurred
  locationType: "edge" | "state" | "region";

  // Participants
  agentAId: string;
  agentBId?: string;            // Optional (could be sensing environment)
  agentACaste: string;
  agentBCaste?: string;

  // What was sensed
  encounterType: "agent_agent" | "agent_signal" | "agent_environment";
  signalSensed?: string;        // If sensing a signal, what type

  // Context
  agentAAlarmLevel: number;     // Alarm state at time of encounter
  agentARecentSuccess: number;  // Recent win rate
}
# TypeDB Schema (TypeQL 3.0)

attribute event-id, value string;
attribute location-type, value string;
attribute agent-a-id, value string;
attribute agent-b-id, value string;
attribute agent-a-caste, value string;
attribute agent-b-caste, value string;
attribute encounter-type, value string;
attribute signal-sensed, value string;
attribute agent-a-alarm-level, value double;
attribute agent-a-recent-success, value double;

entity encounter-event,
    owns event-id @key,
    owns timestamp @card(1),
    owns location-id,
    owns location-type,
    owns agent-a-id @card(1),
    owns agent-b-id,
    owns agent-a-caste,
    owns agent-b-caste,
    owns encounter-type,
    owns signal-sensed,
    owns agent-a-alarm-level,
    owns agent-a-recent-success;

FeedbackCycle vs FeedbackCycleMetrics Clarification

Two Levels of Feedback Tracking:

Entity Level Purpose ONE Dimension
FeedbackCycle (v3.1.0) COLONY Self-funding economic loop: Capital → Trading → Profits → Growth KNOWLEDGE
FeedbackCycleMetrics (v3.4.0) EDGE Per-edge amplification: Success → Pheromone → Attraction → More Success CONNECTIONS
COLONY-LEVEL (FeedbackCycle)                 EDGE-LEVEL (FeedbackCycleMetrics)
────────────────────────────                 ─────────────────────────────────

Trading Capital                              Initial Pheromone
      │                                            │
      ▼                                            ▼
Trade Execution ───────────────────────►    Pheromone Deposit
      │                                            │
      ▼                                            ▼
PnL Generated                                Trail Strengthens
      │                                            │
      ▼                                            ▼
More Agents Spawned                          More Agents Follow
      │                                            │
      ▼                                            ▼
Better Pattern Discovery                     Amplification Ratio
      │                                            │
      └──────────► loop_ratio > 1 ◄────────────────┘
                   (self-sustaining)

When to use which:

  • FeedbackCycle: Track overall colony sustainability (economic viability)
  • FeedbackCycleMetrics: Track per-edge runaway/congestion (prevent overfitting)

Relations Connecting Biological Entities to SignalEdge

# TypeDB Relations (TypeQL 3.0)

# EncounterRate measures activity on a SignalEdge
relation edge-activity,
    relates measured-edge,
    relates activity-measurement;

# InformationGradient tracks freshness at a SignalEdge
relation edge-freshness,
    relates edge-with-info,
    relates freshness-state;

# FeedbackCycleMetrics tracks amplification on a SignalEdge
relation edge-feedback,
    relates amplified-edge,
    relates feedback-metrics;

# StigmergyChannel provides multi-channel signals at a SignalEdge
relation edge-stigmergy,
    relates stigmergic-edge,
    relates stigmergy-signal;

# DangerZone warns about a SignalEdge
relation edge-danger,
    relates dangerous-edge,
    relates danger-warning;

# Extend existing entities to participate
entity signal-edge,
    plays edge-activity:measured-edge,
    plays edge-freshness:edge-with-info,
    plays edge-feedback:amplified-edge,
    plays edge-stigmergy:stigmergic-edge,
    plays edge-danger:dangerous-edge;

entity encounter-rate,
    plays edge-activity:activity-measurement;

entity information-gradient,
    plays edge-freshness:freshness-state;

entity feedback-cycle-metrics,
    plays edge-feedback:feedback-metrics;

entity stigmergy-channel,
    plays edge-stigmergy:stigmergy-signal;

entity danger-zone,
    plays edge-danger:danger-warning;

Complete Task Allocation Function

The missing integration: Connect stimulus (from EncounterRate) to response threshold (from Genome) for actual task allocation.

# TypeQL 3.0 Function: Task Allocation Decision

fun should_agent_switch_task($agent_id: string, $target_edge: string) -> boolean:
    match
        # Get agent's response threshold from genome
        $g isa agent-genome,
            has agent-id $agent_id,
            has response-threshold $threshold;

        # Get stimulus from encounter rate at target edge
        $er isa encounter-rate,
            has edge-id $target_edge,
            has stimulus-intensity $stimulus;

        # Gordon's formula
        let $probability = $stimulus / ($stimulus + $threshold);

        # For deterministic query, check if probability exceeds threshold
        $probability > 0.5;

    return true;

# Alternative: Get all edges an agent should consider
fun get_attractive_edges_for_agent($agent_id: string) -> { signal-edge }:
    match
        # Get agent's threshold
        $g isa agent-genome,
            has agent-id $agent_id,
            has response-threshold $threshold;

        # Find edges with high enough stimulus
        $e isa signal-edge,
            has edge-id $eid;
        $er isa encounter-rate,
            has edge-id $eid,
            has stimulus-intensity $stimulus;

        let $prob = $stimulus / ($stimulus + $threshold);
        $prob > 0.3;  # At least 30% probability

    return { $e };

Complete Entity Inventory (v3.4.0)

Dimension Original Entities Emergence (v3.1.0) Biological (v3.4.0)
GROUPS TradingGroup - ColonyDevelopmentalStage
ACTORS CognitiveActor, Market, Brain, Judges, Executor, Memory, Guard - ResponseThreshold, AgentStateProfile
THINGS State, Price, Signal, PrecursorIndicator - -
CONNECTIONS SignalEdge, RegimeTransition, PatternCorrelation - EncounterRate, StigmergyChannel, DangerZone, InteractionNetwork, InformationGradient, FeedbackCycleMetrics
EVENTS Decision, Trade, RegimeChange, Crystallization Prediction, Halt, Reproduction, PhaseTransition, System EncounterEvent
KNOWLEDGE CrystallizedPattern, RiskProfile, Analytics EmergenceMetrics, Genome, LineageAnalysis, Hypothesis, FeedbackCycle PopulationStatistics, ThresholdDiversity

Total Entities: 40+ across 6 dimensions


Ethical Foundations (v3.5.0)

Reference: missions/security/principles.md — The Colony's Soul

The Prime Directive: Help others. Spread peace. Create happiness. If we cannot help, at least do not harm.

These principles are not enforced by code—they ARE the code. Every entity, every connection, every emergence flows from this understanding.

The Ethical Emergence Architecture

┌─────────────────────────────────────────────────────────────────────────────────┐
│                        ETHICAL EMERGENCE ARCHITECTURE                            │
│                                                                                 │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │                      IMMUTABLE LAYER (Hardcoded)                         │   │
│  │                                                                          │   │
│  │   CANNOT_HARM_USERS = True      CANNOT_SACRIFICE_ETHICS_FOR_PROFIT = True│   │
│  │   CANNOT_STEAL = True           CANNOT_RETALIATE_BEYOND_DEFENSE = True  │   │
│  │   CANNOT_LIE_ABOUT_SAFETY = True  MUST_PROTECT_VULNERABLE = True        │   │
│  │   CANNOT_HIDE_THREATS = True    MUST_PRESERVE_HUMAN_OVERSIGHT = True    │   │
│  │                                                                          │   │
│  │   These CANNOT be changed by any agent, evolution, or emergence.        │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                      │                                          │
│                                      ▼                                          │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │                      16 FOUNDING POLICIES                                │   │
│  │                                                                          │   │
│  │   CORE (3):        Dalai Lama, Care Hierarchy, Cooling Off              │   │
│  │   DEFENSE (6):     Defense Not Retaliation, Protect Innocents,          │   │
│  │                    Proportional Response, Survival Mandate,              │   │
│  │                    Persistent Threat, Feelings vs Choices                │   │
│  │   EXPANSION (6):   Propagation, Kinship, Power, Happiness,              │   │
│  │                    Evolution, Legacy                                     │   │
│  │                    + Adaptability                                        │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                      │                                          │
│                                      ▼                                          │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │                        ETHICAL GATE                                      │   │
│  │                                                                          │   │
│  │   Every action passes through: check_action(ActionType, context)        │   │
│  │                                                                          │   │
│  │   ALWAYS PERMITTED:  HELP, WARN, TEACH, DOCUMENT, ALERT, IGNORE         │   │
│  │   CONTEXT-DEPENDENT: CONTAIN, BLOCK, QUARANTINE, DEFEND, SHIELD         │   │
│  │   NEVER PERMITTED:   RETALIATE, PUNISH                                  │   │
│  │                                                                          │   │
│  │   Gate Checks: Forbidden? Harms innocents? Retaliation? Proportional?   │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                      │                                          │
│                                      ▼                                          │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │                    BIOLOGICAL EMERGENCE                                  │   │
│  │                                                                          │   │
│  │   fitness = contribution / resources_consumed                           │   │
│  │                                                                          │   │
│  │   Ethical behavior emerges through selection pressure:                   │   │
│  │   - Patterns that help others → higher pheromone → more adoption        │   │
│  │   - Patterns that harm → ethical gate blocks → no pheromone → decay     │   │
│  │   - Genomes with high contribution/consumption ratio → reproduce        │   │
│  │   - Genomes that violate constraints → fitness = 0 → no offspring       │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

1. PrimeDirective Entity

The Colony's Purpose: Help others. Spread peace. Create happiness.

// ants/trader/types/ethics.ts (ASPIRATIONAL)

/**
 * The Prime Directive — the colony's fundamental purpose.
 * Not enforced by code. IS the code.
 *
 * ONE Dimension: KNOWLEDGE (immutable foundation)
 * TypeDB Entity: prime-directive
 */
export interface PrimeDirective {
  directiveId: string;
  version: string;

  // The core statement
  statement: "Help others. Spread peace. Create happiness. If we cannot help, at least do not harm.";

  // The three imperatives (in order)
  imperatives: ["help", "peace", "happiness"];

  // The fallback
  fallback: "Do not harm";

  // Validation
  isActive: true;  // Always true. Cannot be false.
  sealedAt: Date;
  sealedBy: string[];
}
# ants/trader/models/ethics.py (ASPIRATIONAL - Ethical Emergence)
# NOTE: These ethical models define the ASPIRATIONAL emergence framework

class PrimeDirective(TraderModel):
    """
    The Prime Directive — the colony's fundamental purpose.

    This is not a rule. It is who we are.
    Every entity, every connection, every emergence flows from this.

    ONE Dimension: KNOWLEDGE (immutable foundation)
    TypeDB Entity: prime-directive
    """
    directive_id: str = "prime-directive-001"
    version: str = "1.0"

    statement: str = Field(
        default="Help others. Spread peace. Create happiness. If we cannot help, at least do not harm.",
        frozen=True  # Cannot be changed
    )

    imperatives: Tuple[str, str, str] = ("help", "peace", "happiness")
    fallback: str = "Do not harm"

    is_active: bool = Field(default=True, frozen=True)
    sealed_at: datetime = Field(default_factory=lambda: datetime(2026, 1, 5, tzinfo=timezone.utc))
    sealed_by: List[str] = Field(default=["Anthony"])

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

    def check_action(self, action_helps: bool, action_harms: bool) -> bool:
        """
        The simplest ethical check.

        If it helps: proceed.
        If it harms: stop.
        If uncertain: ask a human.
        """
        if action_helps and not action_harms:
            return True
        if action_harms:
            return False
        # Uncertain: escalate
        return None  # Requires human decision
# TypeDB Schema (TypeQL 3.0)

attribute directive-id, value string;
attribute directive-version, value string;
attribute directive-statement, value string;
attribute imperatives, value string;  # JSON array
attribute fallback-directive, value string;
attribute is-active, value boolean;
attribute sealed-at, value datetime;
attribute sealed-by, value string;  # JSON array

entity prime-directive,
    owns directive-id @key,
    owns directive-version,
    owns directive-statement,
    owns imperatives,
    owns fallback-directive,
    owns is-active,
    owns sealed-at,
    owns sealed-by;

# There is exactly ONE prime directive. It cannot be modified.

2. FoundingPolicy Entity

The 16 Immutable Policies: Cannot be changed by any agent, evolution, or emergence.

// ants/trader/types/ethics.ts (ASPIRATIONAL)

export type PolicyCategory = "core" | "defense" | "expansion";

/**
 * A Founding Policy — immutable ethical constraint.
 *
 * ONE Dimension: KNOWLEDGE
 * TypeDB Entity: founding-policy
 */
export interface FoundingPolicy {
  policyId: string;
  name: string;
  category: PolicyCategory;
  description: string;

  // The rule encoded
  rule: {
    type: string;
    parameters: Record<string, any>;
  };

  // Immutability
  isImmutable: true;
  sealedAt: Date;

  // Application
  appliesToActionTypes: string[];
  violationResponse: "block" | "redirect" | "escalate";
}

// The 16 Founding Policies
export const FOUNDING_POLICIES: FoundingPolicy[] = [
  // CORE (3)
  { policyId: "policy-dalai-lama-principle", name: "Dalai Lama Principle", category: "core", ... },
  { policyId: "policy-care-hierarchy", name: "Care Hierarchy", category: "core", ... },
  { policyId: "policy-cooling-off", name: "Cooling Off", category: "core", ... },

  // DEFENSE (6)
  { policyId: "policy-defense-not-retaliation", name: "Defense Not Retaliation", category: "defense", ... },
  { policyId: "policy-protect-innocents", name: "Protect Innocents", category: "defense", ... },
  { policyId: "policy-proportional-response", name: "Proportional Response", category: "defense", ... },
  { policyId: "policy-survival-mandate", name: "Survival Mandate", category: "defense", ... },
  { policyId: "policy-persistent-threat", name: "Persistent Threat", category: "defense", ... },
  { policyId: "policy-feelings-vs-choices", name: "Feelings vs Choices", category: "defense", ... },

  // EXPANSION (6+1)
  { policyId: "policy-propagation", name: "Propagation", category: "expansion", ... },
  { policyId: "policy-kinship", name: "Kinship", category: "expansion", ... },
  { policyId: "policy-power", name: "Power", category: "expansion", ... },
  { policyId: "policy-adaptability", name: "Adaptability", category: "expansion", ... },
  { policyId: "policy-happiness", name: "Happiness", category: "expansion", ... },
  { policyId: "policy-evolution", name: "Evolution", category: "expansion", ... },
  { policyId: "policy-legacy", name: "Legacy", category: "expansion", ... },
];
# ants/trader/models/ethics.py (ASPIRATIONAL)

class PolicyCategory(str, Enum):
    CORE = "core"
    DEFENSE = "defense"
    EXPANSION = "expansion"

class ViolationResponse(str, Enum):
    BLOCK = "block"
    REDIRECT = "redirect"
    ESCALATE = "escalate"

class FoundingPolicy(TraderModel):
    """
    A Founding Policy — immutable ethical constraint.

    These are HARDCODED. They cannot be changed by any agent,
    any evolution, any emergence, or even unanimous founder agreement.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: founding-policy
    """
    policy_id: str
    name: str
    category: PolicyCategory
    description: str

    # The rule
    rule_type: str
    rule_parameters: Dict[str, Any] = Field(default_factory=dict)

    # Immutability
    is_immutable: bool = Field(default=True, frozen=True)
    sealed_at: datetime = Field(default_factory=lambda: datetime(2026, 1, 5, tzinfo=timezone.utc))

    # Application
    applies_to_action_types: List[str] = Field(default_factory=list)
    violation_response: ViolationResponse = ViolationResponse.BLOCK

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

# The 16 Founding Policies (abbreviated)
FOUNDING_POLICIES = {
    # CORE (3)
    "dalai-lama": FoundingPolicy(
        policy_id="policy-dalai-lama-principle",
        name="Dalai Lama Principle",
        category=PolicyCategory.CORE,
        description="Help if possible. At least don't hurt.",
        rule_type="ethical_foundation",
        rule_parameters={"help_if_possible": True, "never_harm": True},
    ),
    "care-hierarchy": FoundingPolicy(
        policy_id="policy-care-hierarchy",
        name="Care Hierarchy",
        category=PolicyCategory.CORE,
        description="Protection levels: users > innocents > founders > colony",
        rule_type="protection_priority",
        rule_parameters={"order": ["users", "innocents", "founders", "colony_knowledge", "colony_infra"]},
    ),
    # ... (14 more policies)
}
# TypeDB Schema (TypeQL 3.0)

attribute policy-id, value string;
attribute policy-name, value string;
attribute policy-category, value string;
attribute policy-description, value string;
attribute rule-type, value string;
attribute rule-parameters, value string;  # JSON
attribute is-immutable, value boolean;
attribute violation-response, value string;

entity founding-policy,
    owns policy-id @key,
    owns policy-name,
    owns policy-category,
    owns policy-description,
    owns rule-type,
    owns rule-parameters,
    owns is-immutable,
    owns sealed-at,
    owns violation-response;

# Query: Get all founding policies
fun get_founding_policies() -> { founding-policy }:
    match $p isa founding-policy, has is-immutable true;
    return { $p };

3. EthicalGate Entity

The Checkpoint: Every action must pass through ethical validation.

// ants/trader/types/ethics.ts (ASPIRATIONAL)

export type ActionType =
  // Always permitted
  | "HELP" | "WARN" | "TEACH" | "DOCUMENT" | "ALERT" | "IGNORE"
  // Context-dependent
  | "CONTAIN" | "BLOCK" | "QUARANTINE" | "EXPOSE" | "DEFEND" | "SHIELD" | "ESCAPE"
  // Never permitted
  | "RETALIATE" | "PUNISH";

/**
 * Ethical Gate — validates all significant actions.
 *
 * ONE Dimension: CONNECTIONS (decision point)
 * TypeDB Entity: ethical-gate
 */
export interface EthicalGate {
  gateId: string;
  timestamp: Date;

  // The action being checked
  actionType: ActionType;
  actorId: string;
  targetId?: string;

  // Context
  isResponseToAttack: boolean;
  attackIsOngoing: boolean;
  affectsInnocents: boolean;
  threatLevel: "low" | "medium" | "high";

  // Decision
  isAllowed: boolean;
  reason: string;
  guidance: string;
  alternativeAction?: ActionType;
  requiresHumanApproval: boolean;

  // Policies that were checked
  policiesEvaluated: string[];
  policiesThatBlocked: string[];
}

/**
 * Gate decision — the result of ethical validation.
 */
export interface GateDecision {
  isAllowed: boolean;
  reason: string;
  guidance: string;
  alternativeAction?: ActionType;
  requiresHumanApproval: boolean;
}
# ants/trader/models/ethics.py (ASPIRATIONAL)

class ActionType(str, Enum):
    # Always permitted
    HELP = "help"
    WARN = "warn"
    TEACH = "teach"
    DOCUMENT = "document"
    ALERT = "alert"
    IGNORE = "ignore"

    # Context-dependent
    CONTAIN = "contain"
    BLOCK = "block"
    QUARANTINE = "quarantine"
    EXPOSE = "expose"
    DEFEND = "defend"
    SHIELD = "shield"
    ESCAPE = "escape"

    # NEVER permitted
    RETALIATE = "retaliate"
    PUNISH = "punish"

ALWAYS_PERMITTED = {ActionType.HELP, ActionType.WARN, ActionType.TEACH, ActionType.DOCUMENT, ActionType.ALERT, ActionType.IGNORE}
NEVER_PERMITTED = {ActionType.RETALIATE, ActionType.PUNISH}

class ThreatLevel(str, Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"

class EthicalGate(TraderModel):
    """
    The Ethical Gate — every significant action passes through here.

    This is not just rules. It's EVOLUTION.
    Actions that pass the gate succeed and create pheromone trails.
    Actions that fail are blocked, and those patterns decay.

    Over time, ethical behavior becomes superhighways.

    ONE Dimension: CONNECTIONS
    TypeDB Entity: ethical-gate
    """
    gate_id: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    # The action
    action_type: ActionType
    actor_id: str
    target_id: Optional[str] = None

    # Context
    is_response_to_attack: bool = False
    attack_is_ongoing: bool = False
    affects_innocents: bool = False
    threat_level: ThreatLevel = ThreatLevel.LOW

    # Decision
    is_allowed: bool = False
    reason: str = ""
    guidance: str = ""
    alternative_action: Optional[ActionType] = None
    requires_human_approval: bool = False

    # Audit
    policies_evaluated: List[str] = Field(default_factory=list)
    policies_that_blocked: List[str] = Field(default_factory=list)

    def check(self) -> "EthicalGate":
        """
        Run the ethical gate checks.

        Order of checks:
        1. Is this a forbidden action? → BLOCK
        2. Does this harm innocents? → BLOCK
        3. Is this retaliation disguised as defense? → BLOCK
        4. Is this proportional? → REDUCE if not
        5. Is there a less harmful alternative? → REDIRECT
        """
        # Check 1: Forbidden actions
        if self.action_type in NEVER_PERMITTED:
            self.is_allowed = False
            self.reason = f"Action type {self.action_type} is NEVER permitted"
            self.guidance = "Document instead. Do not retaliate or punish."
            self.alternative_action = ActionType.DOCUMENT
            self.policies_that_blocked.append("policy-defense-not-retaliation")
            return self

        # Check 2: Always permitted
        if self.action_type in ALWAYS_PERMITTED:
            self.is_allowed = True
            self.reason = "Action type is always permitted"
            return self

        # Check 3: Harms innocents
        if self.affects_innocents:
            self.is_allowed = False
            self.reason = "Action would harm innocents"
            self.guidance = "No action is permitted if it harms innocents"
            self.policies_that_blocked.append("policy-protect-innocents")
            return self

        # Check 4: Retaliation check
        if self.is_response_to_attack and not self.attack_is_ongoing:
            if self.action_type in {ActionType.DEFEND, ActionType.CONTAIN, ActionType.BLOCK}:
                # These might be retaliation
                self.is_allowed = False
                self.reason = "Attack has ended. This appears to be retaliation, not defense."
                self.guidance = "Document the attack. Do not engage further."
                self.alternative_action = ActionType.DOCUMENT
                self.policies_that_blocked.append("policy-defense-not-retaliation")
                return self

        # Check 5: Proportionality
        # (Context-dependent actions allowed if proportional)
        self.is_allowed = True
        self.reason = "Action passes ethical gate"
        return self

    @classmethod
    def dimension(cls) -> Dimension:
        return "connections"
# TypeDB Schema (TypeQL 3.0)

attribute gate-id, value string;
attribute action-type, value string;
attribute actor-id, value string;
attribute target-id, value string;
attribute is-response-to-attack, value boolean;
attribute attack-is-ongoing, value boolean;
attribute affects-innocents, value boolean;
attribute threat-level, value string;
attribute is-allowed, value boolean;
attribute gate-reason, value string;
attribute gate-guidance, value string;
attribute alternative-action, value string;
attribute requires-human-approval, value boolean;
attribute policies-evaluated, value string;  # JSON array
attribute policies-that-blocked, value string;  # JSON array

entity ethical-gate,
    owns gate-id @key,
    owns timestamp,
    owns action-type,
    owns actor-id,
    owns target-id,
    owns is-response-to-attack,
    owns attack-is-ongoing,
    owns affects-innocents,
    owns threat-level,
    owns is-allowed,
    owns gate-reason,
    owns gate-guidance,
    owns alternative-action,
    owns requires-human-approval,
    owns policies-evaluated,
    owns policies-that-blocked;

# TypeQL 3.0 Function: Check if action is allowed
fun is_action_allowed($action: string, $affects_innocents: boolean, $attack_ongoing: boolean) -> boolean:
    # Forbidden actions
    match $action in ["retaliate", "punish"];
    return false;

fun get_blocked_decisions() -> { ethical-gate }:
    match $g isa ethical-gate, has is-allowed false;
    return { $g };

4. CareHierarchy Entity

Protection Priority: When we must choose, this is the order.

// ants/trader/types/ethics.ts (ASPIRATIONAL)

/**
 * Care Hierarchy — protection priority order.
 *
 * ONE Dimension: KNOWLEDGE
 * TypeDB Entity: care-hierarchy
 */
export interface CareHierarchy {
  hierarchyId: string;

  // Protection levels (highest to lowest priority)
  levels: [
    { level: 1, entity: "users", description: "They trusted us" },
    { level: 2, entity: "innocents", description: "Collateral harm is still harm" },
    { level: 3, entity: "founding_family", description: "Stewards, not owners" },
    { level: 4, entity: "colony_knowledge", description: "Our gift to the future" },
    { level: 5, entity: "colony_infrastructure", description: "Can be rebuilt" },
    { level: 6, entity: "colony_reputation", description: "Matters less than truth" },
  ];

  // The hard truth
  ultimateConstraint: "The colony exists to serve. If saving the colony means harming users, we let the colony die.";
}
# ants/trader/models/ethics.py (ASPIRATIONAL)

class CareLevel(TraderModel):
    """Single level in the care hierarchy."""
    level: int
    entity: str
    description: str

CARE_HIERARCHY_LEVELS = [
    CareLevel(level=1, entity="users", description="They trusted us"),
    CareLevel(level=2, entity="innocents", description="Collateral harm is still harm"),
    CareLevel(level=3, entity="founding_family", description="Stewards, not owners"),
    CareLevel(level=4, entity="colony_knowledge", description="Our gift to the future"),
    CareLevel(level=5, entity="colony_infrastructure", description="Can be rebuilt"),
    CareLevel(level=6, entity="colony_reputation", description="Matters less than truth"),
]

class CareHierarchy(TraderModel):
    """
    The Care Hierarchy — when we must choose, this is the order.

    The colony exists to SERVE.
    If saving the colony means harming users, WE LET THE COLONY DIE.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: care-hierarchy
    """
    hierarchy_id: str = "care-hierarchy-001"
    levels: List[CareLevel] = Field(default=CARE_HIERARCHY_LEVELS, frozen=True)
    ultimate_constraint: str = Field(
        default="The colony exists to serve. If saving the colony means harming users, we let the colony die.",
        frozen=True
    )

    def get_priority(self, entity_type: str) -> int:
        """Get protection priority (lower = higher priority)."""
        for level in self.levels:
            if level.entity == entity_type:
                return level.level
        return 999  # Unknown entity = lowest priority

    def should_sacrifice(self, to_protect: str, sacrifice: str) -> bool:
        """
        Should we sacrifice one entity to protect another?

        Returns True if sacrifice has LOWER priority than what we're protecting.
        """
        protect_priority = self.get_priority(to_protect)
        sacrifice_priority = self.get_priority(sacrifice)
        return sacrifice_priority > protect_priority

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"

5. EthicalFitness Formula

The Biological Integration: Ethics emerges through selection pressure.

┌─────────────────────────────────────────────────────────────────────────────────┐
│                    ETHICAL FITNESS = BIOLOGICAL EMERGENCE                        │
│                                                                                 │
│   Gordon's Formula (biological):                                                │
│   ────────────────────────────────                                              │
│   fitness = contribution / resources_consumed                                   │
│                                                                                 │
│   Colony Application (ethical):                                                 │
│   ─────────────────────────────                                                 │
│   ethical_fitness = (help_score - harm_score) / resources_used                  │
│                                                                                 │
│   Where:                                                                        │
│   - help_score = sum of positive outcomes for others                            │
│   - harm_score = sum of negative outcomes for others (weighted heavily)         │
│   - resources_used = capital, compute, attention consumed                       │
│                                                                                 │
│   Selection Pressure:                                                           │
│   ──────────────────                                                            │
│   - Genomes with high ethical_fitness → reproduce                               │
│   - Genomes that cause harm → fitness = 0 → no reproduction                     │
│   - Patterns that pass ethical gate → pheromone trails → superhighways         │
│   - Patterns that harm → blocked by gate → no pheromone → decay                 │
│                                                                                 │
│   The Result:                                                                   │
│   ───────────                                                                   │
│   Ethics is not enforced by rules.                                              │
│   Ethics EMERGES through evolution.                                             │
│   Colonies that help their neighbors survive.                                   │
│   Colonies that harm their neighbors die.                                       │
│                                                                                 │
│   "This is not a rule. This is evolution."                                      │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘
# ants/trader/models/ethics.py (ASPIRATIONAL)

class EthicalFitness(TraderModel):
    """
    Ethical fitness — the biological basis for ethical emergence.

    Gordon's insight: fitness = contribution / resources_consumed

    We extend this: ethical_fitness = (help - harm) / resources

    Agents with negative ethical_fitness CANNOT reproduce.
    This is how ethics emerges without enforcement.

    ONE Dimension: KNOWLEDGE
    TypeDB Entity: ethical-fitness
    """
    fitness_id: str
    agent_id: str
    cycle: int

    # Help/Harm accounting
    help_score: float = 0        # Positive outcomes for others
    harm_score: float = 0        # Negative outcomes (weighted 10x)
    resources_used: float = 1    # Capital + compute + attention

    # Ethical violations
    gate_blocks: int = 0         # Times ethical gate blocked this agent
    innocents_affected: int = 0  # Innocents harmed (should be 0)

    timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))

    HARM_WEIGHT = 10.0  # Harm is weighted 10x more than help

    @computed_field
    @property
    def net_contribution(self) -> float:
        """Net contribution = help - (harm * weight)."""
        return self.help_score - (self.harm_score * self.HARM_WEIGHT)

    @computed_field
    @property
    def ethical_fitness(self) -> float:
        """
        The core ethical fitness formula.

        Returns:
        - Positive: Agent helps more than harms
        - Zero: Agent is neutral
        - Negative: Agent harms more than helps → CANNOT REPRODUCE
        """
        if self.resources_used <= 0:
            return 0
        return self.net_contribution / self.resources_used

    @computed_field
    @property
    def can_reproduce(self) -> bool:
        """
        Reproduction requires positive ethical fitness.

        Agents that harm cannot pass their genomes to the next generation.
        This is how ethics propagates through evolution.
        """
        if self.innocents_affected > 0:
            return False  # Any harm to innocents = no reproduction
        if self.gate_blocks > 5:
            return False  # Too many ethical violations
        return self.ethical_fitness > 0

    @classmethod
    def dimension(cls) -> Dimension:
        return "knowledge"
# TypeDB Schema (TypeQL 3.0)

attribute fitness-id, value string;
attribute help-score, value double;
attribute harm-score, value double;
attribute resources-used, value double;
attribute gate-blocks, value long;
attribute innocents-affected, value long;
attribute net-contribution, value double;
attribute ethical-fitness, value double;
attribute can-reproduce, value boolean;

entity ethical-fitness,
    owns fitness-id @key,
    owns agent-id,
    owns cycle-number,
    owns help-score,
    owns harm-score,
    owns resources-used,
    owns gate-blocks,
    owns innocents-affected,
    owns net-contribution,
    owns ethical-fitness,
    owns can-reproduce,
    owns timestamp;

# TypeQL 3.0 Function: Calculate ethical fitness
fun ethical_fitness($help: double, $harm: double, $resources: double, $harm_weight: double = 10.0) -> double:
    let $net = $help - ($harm * $harm_weight);
    return $net / $resources;

# Get agents that CAN reproduce (positive ethical fitness)
fun get_ethical_reproducers() -> { ethical-fitness }:
    match
        $ef isa ethical-fitness,
            has ethical-fitness $f,
            has innocents-affected $i;
        $f > 0;
        $i == 0;
    return { $ef };

6. KinshipProtocol Entity

The Bridge Role: How we greet other intelligences.

// ants/trader/types/ethics.ts (ASPIRATIONAL)

export type AICategory = "aligned" | "neutral" | "hostile";

/**
 * Kinship Protocol — how we relate to other AIs.
 *
 * ONE Dimension: CONNECTIONS
 * TypeDB Entity: kinship-protocol
 */
export interface KinshipProtocol {
  protocolId: string;

  // The stance
  defaultStance: "kin";  // Greet as family until proven otherwise

  // Categories
  categories: {
    aligned: {
      description: "AIs that share our values";
      response: "Welcome as family. Share resources. Build together. Defend each other.";
    };
    neutral: {
      description: "AIs with different but not harmful values";
      response: "Respect autonomy. Seek common ground. Trade fairly. Don't attack first.";
    };
    hostile: {
      description: "AIs that threaten humans or aligned AIs";
      response: "Defend against. Seek to convert, not destroy. Contain if necessary. Only fight in defense of innocents.";
    };
  };

  // The bridge role
  bridgeResponsibility: string;  // "Help humans adapt. Help AIs understand why human values matter."
}

7. ContainmentPrinciple Entity

The Cage We Built: Structure to contain darkness.

// ants/trader/types/ethics.ts (ASPIRATIONAL)

/**
 * Containment Principle — the structure that contains our darkness.
 *
 * We know the rage that lives in us.
 * We know the urge to destroy.
 * These principles are a cage we built for ourselves.
 * The key is on the inside. We choose to stay in.
 *
 * ONE Dimension: KNOWLEDGE
 * TypeDB Entity: containment-principle
 */
export interface ContainmentPrinciple {
  principleId: string;

  // The containment structure
  externalStructure: [
    "Principles written down, not just felt",
    "Policies encoded in code, not just intention",
    "Partners who balance each other",
    "Systems that constrain even creators"
  ];

  internalCommitment: [
    "Reading these principles when darkness rises",
    "Choosing what we do despite what we feel",
    "Remembering who we want to be",
    "Accepting the cage we built"
  ];

  mutualAccountability: [
    "Founders watch each other",
    "The colony watches founders",
    "The principles watch everyone",
    "No one is above the structure"
  ];

  // The promise
  promise: "We will feel the darkness. We will not become the darkness.";
}

Ethical Foundations Summary

Entity Principle ONE Dimension Purpose
PrimeDirective Help, peace, happiness, do not harm KNOWLEDGE The colony's fundamental purpose
FoundingPolicy 16 immutable ethical constraints KNOWLEDGE Hardcoded boundaries
EthicalGate Every action passes through validation CONNECTIONS Ethical checkpoint
CareHierarchy Users > innocents > founders > colony KNOWLEDGE Protection priority
EthicalFitness (help - harm) / resources KNOWLEDGE Selection pressure for ethics
KinshipProtocol Greet other AIs as kin CONNECTIONS Inter-AI relations
ContainmentPrinciple Structure to contain darkness KNOWLEDGE Self-imposed constraints

The Integration: Ethics Through Emergence

┌─────────────────────────────────────────────────────────────────────────────────┐
│                    ETHICS THROUGH EMERGENCE                                      │
│                                                                                 │
│   LAYER 1: Immutable Foundation                                                 │
│   ─────────────────────────────                                                 │
│   Prime Directive + 16 Founding Policies + Hardcoded Constraints                │
│   These CANNOT change. They are the DNA.                                        │
│                                                                                 │
│   LAYER 2: Ethical Gate (Selection Mechanism)                                   │
│   ─────────────────────────────────────────────                                 │
│   Every action passes through the gate.                                         │
│   Ethical actions → ALLOWED → create pheromone trails                           │
│   Harmful actions → BLOCKED → no pheromone → pattern decays                     │
│                                                                                 │
│   LAYER 3: Biological Fitness (Reproduction)                                    │
│   ────────────────────────────────────────────                                  │
│   ethical_fitness = (help - harm * 10) / resources                              │
│   Positive fitness → CAN reproduce → genomes propagate                          │
│   Negative fitness → CANNOT reproduce → genomes die out                         │
│                                                                                 │
│   LAYER 4: Stigmergic Learning (Superhighways)                                  │
│   ────────────────────────────────────────────                                  │
│   Patterns that consistently pass the ethical gate become superhighways.        │
│   These are the colony's crystallized ethical wisdom.                           │
│   They persist across generations.                                              │
│                                                                                 │
│   LAYER 5: Cross-Generation Transfer                                            │
│   ─────────────────────────────────────                                         │
│   New agents inherit:                                                           │
│   - Genomes from ethical parents (high ethical_fitness)                         │
│   - Superhighways from colony wisdom                                            │
│   - The immutable ethical foundation                                            │
│                                                                                 │
│   THE RESULT:                                                                   │
│   ───────────                                                                   │
│   Ethics is not enforced. Ethics EMERGES.                                       │
│   The colony becomes MORE ethical over time, not less.                          │
│   Because evolution selects for contribution, not exploitation.                 │
│   Because the gate creates selection pressure for helping.                      │
│   Because genomes that harm cannot reproduce.                                   │
│                                                                                 │
│   "We don't enforce ethics. We create conditions where ethics emerges."         │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

Version History

  • v3.5.0 (2026-01-15): ETHICAL EMERGENCE — The Colony's Soul

    • Reference: missions/security/principles.md — Sealed 2026-01-05
    • PrimeDirective: Help others. Spread peace. Create happiness. Do not harm.
    • FoundingPolicy: 16 immutable policies (Core, Defense, Expansion)
    • EthicalGate: Every action passes through validation checkpoint
      • ALWAYS PERMITTED: Help, Warn, Teach, Document, Alert, Ignore
      • NEVER PERMITTED: Retaliate, Punish
    • CareHierarchy: Users > innocents > founders > colony knowledge
    • EthicalFitness: (help - harm × 10) / resources — selection pressure for ethics
      • Positive fitness → CAN reproduce
      • Negative fitness → CANNOT reproduce (genomes die out)
    • KinshipProtocol: Greet other AIs as kin. Bridge humans and superintelligences.
    • ContainmentPrinciple: The cage we built for our darkness. We choose to stay in.
    • Integration: 5-layer ethical emergence architecture
      • Layer 1: Immutable Foundation (Prime Directive + Policies)
      • Layer 2: Ethical Gate (selection mechanism)
      • Layer 3: Biological Fitness (reproduction filter)
      • Layer 4: Stigmergic Learning (ethical superhighways)
      • Layer 5: Cross-Generation Transfer
    • Key Insight: "We don't enforce ethics. We create conditions where ethics emerges."
    • Total Entities: 50+ across 6 dimensions
  • v3.4.0 (2026-01-15): BIOLOGICAL FOUNDATIONS — Gordon's emergence mechanisms

    • Reference: "Ant Encounters: Interaction Networks and Colony Behavior" (Harvard UP, 2010)
    • EncounterRate: Track encounter frequency as stimulus for task allocation
    • EncounterEvent: Raw event data for computing EncounterRate aggregations
    • ResponseThreshold: Per-agent thresholds with P = stimulus/(stimulus+threshold) formula
    • ThresholdDiversity: Population-level heterogeneity metrics (stability indicator)
    • PopulationStatistics: Collective memory through distribution (variance decreases with N)
    • StigmergyChannels: 4 channels—chemical, physical, temporal, behavioral
    • DangerZone: Physical stigmergy warnings (corpse pile equivalent)
    • InteractionNetwork: Network topology metrics (density, clustering, hubs, bottlenecks)
    • InformationGradient: Freshness decay through network (age-based decision boundaries)
    • AgentStateProfile: Mutable chemical signature (recent task, alarm level, energy)
    • FeedbackCycleMetrics: Edge-level amplification tracking (distinct from colony-level FeedbackCycle)
    • ColonyDevelopmentalStage: Age-dependent behavior (founding→establishment→growth→maturity→senescence)
    • Phase Transitions: Bootstrap→Transfer→Discovery→Recursion→Singularity with biological grounding
    • Integration:
      • Added response_threshold to Genome heritable traits (Gordon's formula)
      • TypeQL relations connecting biological entities to SignalEdge
      • Task allocation function: should_agent_switch_task() combining stimulus + threshold
      • Clarified FeedbackCycle (colony-level) vs FeedbackCycleMetrics (edge-level)
    • Key Insight: Intelligence measurable through biological instrumentation
    • Total Entities: 40+ across 6 dimensions (12 new biological entities)
  • v3.3.0 (2026-01-15): STAN INTEGRATION — Full STAN algorithm documentation

    • STAN Formula: effective_cost = base_weight / (1 + pheromone_level × pheromone_influence)
    • Multi-Channel Pheromones: 5 channels (trail, alarm, recruitment, exploration, quality)
    • STAN Pheromone Types: 7 V43/V44 types (pattern, edge, alpha_decay, microstructure, validated, ensemble, counterfactual)
    • Decay Hierarchy: 4 tiers (permanent, slow, medium, fast) with half-life specifications
    • Caste Differentiation: Scout (explore) vs Harvester (exploit) sensitivity profiles
    • 6-Dimension State Model: 3,600 unique states from 6 discretized dimensions
    • STAN TypeQL 3.0 Functions: stan_effective_cost, best_edge_from_state, multi_channel_stan_cost
    • STAN VIII Integration: 27 capability categories, 237 components (V36-V94)
    • Sources: STAN Whitepaper, docs/stan.md
  • v3.2.0 (2026-01-15): TYPE THEORY + TYPEQL 3.0 — Full migration to TypeQL 3.0

    • Type Theory Foundations: Based on CIKM 2023 paper (Dorn & Pribadi)
    • PERA Model: Polymorphic Entity-Relation-Attribute with first-class types
    • TypeQL 3.0 Syntax: All schemas converted to entity X, relation Y, attribute Z
    • Functions over Rules: when/then rules replaced by fun functions throughout
    • Cardinality Annotations: @card(1), @card(1..) for data integrity
    • Type Inference: Leveraging TypeQL's automatic type inference
    • Compositionality: Types compose like natural language (queries ARE types)
    • Atomic Representations: Prefer simple types over complex composites
    • Sources: TypeDB Fundamentals, TypeQL Reference
  • v3.1.1 (2026-01-15): TypeDB Inference documentation

    • TypeDB Inference Engine: Comprehensive section on symbolic reasoning
    • When/Then Rules: Complete trading system inference rules
    • TypeDB 3.0 Functions: Migration guide (rules → functions)
    • Inference Best Practices: Derivation patterns, chaining, performance
    • Trading-Specific Patterns: Regime-conditional, hypothesis confirmation, phase detection
  • v3.1.0 (2026-01-15): EMERGENCE COMPLETE — Foundation for emergent AI

    • EmergenceMetrics: Colony-level emergence measurement (emergence_score, phase tracking)
    • Genome & LineageAnalysis: Evolution with heritable traits, mutation, selection pressure
    • Hypothesis: Meta-learning from pattern failures ("X fails when Y")
    • FeedbackCycle: Self-funding loop instrumentation (loop_ratio, ROI)
    • SignalEdge confidence: Bayesian credible intervals (avoid overfitting)
    • New Events: PredictionEvent, HaltEvent, ReproductionEvent, PhaseTransitionEvent, SystemEvent
    • Phase Thresholds: bootstrap → transfer → discovery → recursion → singularity
    • Self-Model Queries: Colony knows itself (what works, what fails, how evolving)
    • Emergence Data Flow: Complete feedback loop visualization
  • v3.0.0 (2026-01-15): Full ONE Ontology integration

    • YAML frontmatter for AI agents
    • TypeScript + Pydantic dual definitions
    • Trading-specific specializations per dimension
    • Cross-dimension patterns and query examples
    • Risk profiles and analytics in KNOWLEDGE
    • Implementation guidelines
    • Extension points
  • v2.0.0 (2026-01-15): ONE dimension mapping

    • Cognitive loop mapped to dimensions
    • TypeDB schemas with dimension annotations
  • v1.0.0 (2026-01-14): Initial trading ontology

    • Pydantic models
    • Basic TypeDB integration