// Organism schema — FlatBuffers
//
// Separates:
//   Weights  (shared cortical hardware, Arc-shareable)
//   Session  (per-persona state, isolated)
//   Memory   (episodic store with per-alter access control)
//
// File layout:
//   organism.weights.fb  — one per organism (shared across personas)
//   persona_X.session.fb — one per persona
//   memory.fb            — shared episodic store (existing isis.fbs)
//   barriers.fb          — dissociative access control

namespace isis.organism;

// ─── Shared types ────────────────────────────────────────

enum Precision : byte {
    F32 = 0,
    F16 = 1,
    I8  = 2,
}

/// Dense matrix stored in chosen precision.
/// All weight matrices use this: synapses, NLM stages, projectors.
table Matrix {
    rows: uint32;
    cols: uint32;
    precision: Precision;
    f32_data: [float];
    f16_data: [uint16];
    i8_data: [int8];
    i8_scale: float;
}

/// Bias vector.
table Bias {
    precision: Precision;
    f32_data: [float];
    f16_data: [uint16];
    i8_data: [int8];
    i8_scale: float;
}

// ─── Region definition ───────────────────────────────────

/// Per-neuron MLP weights within a region.
table NlmStage {
    weights: Matrix;     // [n_neurons × out_per × in_per]
    biases: Bias;        // [n_neurons × out_per]
    n_neurons: uint32;
    in_per: uint32;
    out_per: uint32;
}

/// A brain region's learned weights.
table RegionWeights {
    name: string;        // "input", "attention", "output", "motor", etc.
    n_neurons: uint32;
    memory_length: uint32;
    inhibitory_fraction: float;
    inhibitory_mask: [bool];
    nlm_stage1: NlmStage;
    nlm_stage2: NlmStage;   // null if nlm_depth < 2
    start_trace: [float];   // initial trace state
    start_activated: [float]; // initial activation
}

/// Inter-region synapse weights.
table SynapseWeights {
    from_region: string;
    to_region: string;
    weight: Matrix;      // [out_dim*2 × in_dim] (×2 for GLU)
    bias: Bias;          // [out_dim*2]
}

// ─── Weights file (shared across personas) ───────────────

table OrganismWeights {
    version: uint32;

    // Architecture config
    iterations: uint32;
    d_model: uint32;
    d_input: uint32;
    n_sync_out: uint32;
    n_sync_action: uint32;
    motor_threshold: float;

    // Brain regions (variable count — not hardcoded to 8)
    regions: [RegionWeights];

    // Inter-region synapses (variable count)
    synapses: [SynapseWeights];

    // Projectors
    global_projector: Matrix;
    global_projector_bias: Bias;
    output_projector: Matrix;
    output_projector_bias: Bias;
    logit_projector: Matrix;
    logit_projector_bias: Bias;

    // Sync pair topology (deterministic from seed, but stored for portability)
    sync_out_left: [uint32];
    sync_out_right: [uint32];
    sync_out_decay: [float];
    sync_action_left: [uint32];
    sync_action_right: [uint32];
    sync_action_decay: [float];

    // Position predictor weights (optional)
    position_predictor_gate: Matrix;
    position_predictor_content: Matrix;
    position_predictor_final: Matrix;

    // Organism-level learned parameters
    embeddings: Matrix;         // [vocab_size × embed_dim]
    sensory_layers: [Matrix];   // sensory MLP weight matrices
    sensory_biases: [Bias];
    output_proj: Matrix;        // [vocab_size × n_sync_out]
    output_proj_bias: Bias;

    // Metadata
    vocab_size: uint32;
    embed_dim: uint32;
    sensory_depth: uint32;
    context_len: uint32;
    tokens_seen: uint64;
    sleep_cycles: uint64;
    created_at: float64;
}

// ─── Session file (per-persona) ──────────────────────────

/// Neuromodulator baseline — each persona's emotional temperament.
table NeuromodBaseline {
    dopamine: float;
    serotonin: float;
    norepinephrine: float;
    acetylcholine: float;
    curiosity: float;
    anxiety: float;
}

/// Hippocampal content-addressable memory state.
table HippocampalState {
    capacity: uint32;
    key_dim: uint32;
    value_dim: uint32;
    keys: [float];        // [capacity × key_dim]
    values: [float];      // [capacity × value_dim]
    strengths: [float];   // [capacity]
    write_ptr: uint32;
    count: uint32;
}

/// Per-region mutable state (noise, usefulness tracking).
table RegionState {
    region_name: string;
    noise_scale: [float];      // [n_neurons]
    usefulness_ema: [float];   // [n_neurons]
}

/// Hebbian plasticity state per region.
table HebbianState {
    region_name: string;
    running_mean: [float];     // [n_neurons]
    baseline_mean: [float];
    baseline_var: [float];
    calibrated: bool;
}

/// Replay buffer entry for prioritized consolidation.
table ReplayEntry {
    observation: [float];
    surprise: float;
    timestamp: uint64;
}

/// A persona's complete session state.
/// This is everything that makes one persona different from another
/// running on the same shared weights.
table PersonaSession {
    version: uint32;

    // Identity
    name: string;              // persona name
    created_at: float64;

    // Emotional temperament
    neuromod_baseline: NeuromodBaseline;

    // Episodic memory (per-persona hippocampal state)
    hippo: HippocampalState;
    hippo_retrieval: [float];

    // Basal ganglia learning state
    bg_eligibility: [float];
    bg_da_baseline: float;
    bg_weight_delta: [float];

    // Per-region mutable state
    region_states: [RegionState];

    // Per-region Hebbian state
    hebbian_states: [HebbianState];

    // Sleep consolidation traces (transient, may be empty)
    sleep_trace_count: uint32;

    // Replay buffer
    replay_entries: [ReplayEntry];
    replay_capacity: uint32;

    // Training state
    hebbian_enabled: bool;
    tokens_processed: uint64;
    gamma_cycles_total: uint64;
}

// ─── Dissociative barriers ───────────────────────────────

/// Per-persona access control over shared episodic memory.
/// Each persona can see different episodes with different strength.
table EpisodeAccess {
    episode_index: uint32;     // index into MemoryBank.alters[].episodes[]
    access_level: float;       // 0.0 = walled off, 1.0 = full access
}

table PersonaBarrier {
    persona_name: string;
    episode_access: [EpisodeAccess];
}

table DissociativeBarriers {
    version: uint32;
    barriers: [PersonaBarrier];
    // Global integration level: 0.0 = fully dissociated, 1.0 = fully integrated
    integration_level: float;
}

// ─── Root types ──────────────────────────────────────────

root_type OrganismWeights;
file_identifier "orgw";
file_extension "weights.fb";

// For session files, use PersonaSession as root:
// root_type PersonaSession;
// file_identifier "orgs";
// file_extension "session.fb";

// For barrier files, use DissociativeBarriers as root:
// root_type DissociativeBarriers;
// file_identifier "orgb";
// file_extension "barriers.fb";
