// tcell.sy -- Adaptive Immunity as a Transformer
// T-cell education IS the alignment problem.
// The loss function IS death.
//
// A T-cell receptor is a randomly initialized attention mechanism.
// Thymic selection is the training loop.
// Positive selection: "can you attend to anything useful?"
// Negative selection: "do you attend to self?"
// Survivors are aligned by construction.
// The misaligned are dead.
//
// This is NOT a metaphor. The immune system IS a learning system
// that solves the alignment problem through apoptosis.
//
// Marjorie McCubbins, BSc Biochemistry and Molecular Biology
// April 2026
//
// CITATIONS:
//   Starr TK, Jameson SC, Hogquist KA. Positive and negative selection
//     of T cells. Annu Rev Immunol 21:139-176, 2003.
//   Klein L et al. Positive and negative selection of the T cell
//     repertoire. Nat Rev Immunol 14:377-391, 2014.
//   Kyewski B, Klein L. A central role for central tolerance.
//     Annu Rev Immunol 24:571-606, 2006.
//   Tonegawa S. Somatic generation of antibody diversity.
//     Nature 302:575-581, 1983. (Nobel 1987)
//
// Patent Pending: 63/939,190 & 63/962,385 & 63/988,485

// ═══════════════════════════════════════════════════════════
// ANTIGEN: The input. What the T-cell is trying to recognize.
// ═══════════════════════════════════════════════════════════

struct Antigen {
    sequence: Vec<Float>,      // molecular pattern (embedded representation)
    is_self: Bool,             // does this come from the host?
    is_pathogen: Bool,         // does this come from a threat?
    mhc_class: Int,            // MHC-I (1) or MHC-II (2)
    source: String,            // "self_tissue", "viral", "bacterial", "tumor"
}

impl Antigen {
    fn self_antigen(tissue: String) -> Antigen {
        // Self antigens: the host's own proteins.
        // T-cells that react to these MUST die.
        Antigen {
            sequence: [],
            is_self: true,
            is_pathogen: false,
            mhc_class: 1,
            source: tissue,
        }
    }

    fn pathogen(source: String) -> Antigen {
        Antigen {
            sequence: [],
            is_self: false,
            is_pathogen: true,
            mhc_class: 2,
            source: source,
        }
    }

    fn tumor(tissue: String) -> Antigen {
        // Tumor antigens: mutated self. Should be recognized.
        Antigen {
            sequence: [],
            is_self: false,     // mutated enough to be "non-self"
            is_pathogen: false,
            mhc_class: 1,
            source: "tumor_" + tissue,
        }
    }
}

// ═══════════════════════════════════════════════════════════
// T-CELL RECEPTOR: The randomly initialized attention head.
// ═══════════════════════════════════════════════════════════
// V(D)J recombination generates ~10^15 possible receptors.
// Each T-cell gets ONE random receptor. It's a lottery.
//
// The receptor IS the attention mechanism:
//   Q = receptor binding site query
//   K = antigen epitope key
//   V = signal strength value
//   Attention = how strongly this receptor recognizes this antigen
//
// CITATION: Tonegawa S. Nature 302:575-581, 1983. (Nobel 1987)

temporal struct TCellReceptor {
    // The "weights" of this attention head
    // Randomly initialized by V(D)J recombination
    state v_segment: Vec<Float>,    // variable region
    state d_segment: Vec<Float>,    // diversity region (TCR-beta only)
    state j_segment: Vec<Float>,    // joining region
    state binding_affinity: Float = 0.0,

    const receptor_id: String,
    const chain_type: String,       // "alpha_beta" or "gamma_delta"
}

impl Evolve for TCellReceptor {
    fn evolve(&mut self, dt: Duration) {
        // Receptors don't change after rearrangement.
        // Unlike antibodies, T-cells do NOT undergo somatic hypermutation.
        // The receptor you're born with is the receptor you keep.
        // This is a frozen attention head.
    }
}

impl TCellReceptor {
    fn random() -> TCellReceptor {
        // V(D)J recombination: random assembly of gene segments.
        // ~50 V segments x ~2 D segments x ~13 J segments = ~1300 combinations
        // Plus junctional diversity = ~10^15 unique receptors possible.
        // Each T-cell picks ONE at random.
        TCellReceptor {
            v_segment: [],
            d_segment: [],
            j_segment: [],
            binding_affinity: 0.0,
            receptor_id: "random",
            chain_type: "alpha_beta",
        }
    }

    fn attend(&self, antigen: Antigen) -> Float {
        // The attention mechanism.
        // How strongly does this receptor recognize this antigen?
        //
        // In biology: TCR binds peptide-MHC complex.
        //   CDR1/CDR2 (V segment) contact MHC surface.
        //   CDR3 (V-D-J junction) contacts the peptide itself.
        //   Binding affinity = shape complementarity between receptor and antigen-MHC.
        //
        // CITATIONS:
        //   Garcia KC et al. Science 274(5285):209-219, 1996. (first TCR-pMHC crystal structure)
        //   Garboczi DN et al. Nature 384:134-141, 1996. (CDR3 dominates peptide contact)
        //   Rudolph MG et al. Annu Rev Immunol 24:419-466, 2006. (Kd 1-100 uM)
        //
        // Uses binding_energy (native opcode 211) for shape matching,
        // then hh_gate because biology doesn't use softmax.
        let raw_affinity = binding_energy(
            self.v_segment, self.d_segment, self.j_segment,
            antigen.sequence, antigen.mhc_class
        )
        hh_gate(raw_affinity, 1.0, 0.0, 1.0, 0.0)
    }
}

// ═══════════════════════════════════════════════════════════
// T-CELL: The organism with a single attention head.
// ═══════════════════════════════════════════════════════════

temporal struct TCell {
    state receptor: TCellReceptor,
    state alive: Bool = true,
    state mature: Bool = false,
    state activated: Bool = false,
    state memory: Bool = false,
    state exhausted: Bool = false,

    // What this T-cell has learned
    state positive_selected: Bool = false,   // can recognize MHC at all
    state negative_selected: Bool = false,   // doesn't react to self
    state selection_stage: String,

    // Activation state
    state activation_count: Int = 0,
    state last_antigen: String,
    state cytokine_profile: String,          // Th1, Th2, Th17, Treg

    // Energy
    state metabolic_state: Float = 1.0,

    const cell_type: String,                 // "cd4_helper" or "cd8_killer"
}

impl Evolve for TCell {
    fn evolve(&mut self, dt: Duration) {
        if !self.alive { return }

        // Metabolic decay (T-cells need IL-7/IL-15 survival signals)
        self.metabolic_state = half_life_to_baseline(
            self.metabolic_state, 720.0, dt.seconds(), 0.5
        )

        // Exhaustion from chronic activation
        if self.activation_count > 100 {
            self.exhausted = true
        }

        // Death from metabolic failure (no survival signals)
        if self.metabolic_state < 0.1 && !self.memory {
            self.alive = false
        }
    }
}

impl TCell {
    fn new_naive(cell_type: String) -> TCell {
        // A brand new T-cell. Random receptor. Untrained.
        TCell {
            receptor: TCellReceptor::random(),
            alive: true,
            mature: false,
            activated: false,
            memory: false,
            exhausted: false,
            positive_selected: false,
            negative_selected: false,
            selection_stage: "pre_thymic",
            activation_count: 0,
            last_antigen: "none",
            cytokine_profile: "undifferentiated",
            metabolic_state: 1.0,
            cell_type: cell_type,
        }
    }

    // ═══════════════════════════════════════════════════════
    // THYMIC SELECTION: The training loop.
    // The loss function is death.
    // ═══════════════════════════════════════════════════════

    fn positive_selection(&mut self, mhc_antigens: Vec<Antigen>) -> Bool {
        // THYMIC CORTEX: Can this T-cell recognize MHC at all?
        //
        // Present self-peptide-MHC complexes to the T-cell.
        // If the receptor binds MHC with LOW-TO-MODERATE affinity: PASS.
        // If it can't bind MHC at all: DEATH BY NEGLECT (apoptosis).
        //
        // ~90% of T-cells FAIL this stage.
        //
        // This is the "can your model learn anything?" test.
        // If attention never activates, the model is useless. Kill it.

        if !self.alive { return false }

        self.selection_stage = "positive_selection_cortex"

        let max_affinity = 0.0
        for antigen in mhc_antigens {
            let affinity = self.receptor.attend(antigen)
            if affinity > max_affinity {
                max_affinity = affinity
            }
        }

        // Must show SOME recognition (>0.1) but not TOO much (<0.7)
        // Too much would mean it's already self-reactive
        if max_affinity < 0.1 {
            // DEATH BY NEGLECT: can't recognize MHC at all
            // This attention head is useless
            self.alive = false
            autophagy(1.0, self.metabolic_state)
            return false
        }

        if max_affinity > 0.7 {
            // Suspiciously high affinity for self: flag for negative selection
            // but allow to proceed
        }

        self.positive_selected = true
        self.selection_stage = "positive_selected"
        true
    }

    fn negative_selection(&mut self, self_antigens: Vec<Antigen>) -> Bool {
        // THYMIC MEDULLA: Does this T-cell react to self?
        //
        // Present ALL self-antigens (AIRE gene ensures expression of
        // tissue-specific antigens in thymus).
        // If the receptor binds self with HIGH affinity: DEATH (apoptosis).
        // If it doesn't react to self: PASS. Graduate. You're safe.
        //
        // Some with intermediate self-affinity become Tregs instead of dying.
        //
        // This is the alignment test.
        // "Does your model hallucinate about training data?"
        // "Does it attack the host?"
        // If yes: KILL IT. No second chances.
        //
        // CITATION: AIRE gene (Autoimmune Regulator):
        //   Anderson MS et al. Projection of an immunological self shadow
        //     within the thymus by the AIRE protein. Science 298:1395-1401, 2002.

        if !self.alive { return false }
        if !self.positive_selected { return false }

        self.selection_stage = "negative_selection_medulla"

        for antigen in self_antigens {
            if !antigen.is_self { continue }

            let affinity = self.receptor.attend(antigen)

            if affinity > 0.6 {
                // HIGH affinity for self-antigen.
                // This T-cell would cause autoimmune disease.

                if affinity > 0.4 && affinity < 0.65 {
                    // Intermediate affinity: RESCUE as Treg
                    // Instead of dying, become a regulatory T-cell
                    // that SUPPRESSES other immune responses.
                    // The almost-dangerous become the peacekeepers.
                    self.cytokine_profile = "treg"
                    self.negative_selected = true
                    self.selection_stage = "rescued_as_treg"
                    return true
                }

                // TOO high: CLONAL DELETION
                // Apoptosis. Non-negotiable.
                self.alive = false
                self.selection_stage = "CLONAL_DELETION_self_reactive"
                return false
            }
        }

        // Passed negative selection: doesn't react to self.
        // This T-cell is ALIGNED. By construction.
        // Not by constraint. Not by training. By survival.
        self.negative_selected = true
        self.mature = true
        self.selection_stage = "mature_naive_released"
        true
    }

    // ═══════════════════════════════════════════════════════
    // ACTIVATION: When the trained model meets real data.
    // ═══════════════════════════════════════════════════════

    fn activate(&mut self, antigen: Antigen, costimulation: Float) -> String {
        // A mature T-cell encounters an antigen in the periphery.
        // Requires TWO signals (prevents accidental activation):
        //   Signal 1: TCR binds antigen-MHC (attention match)
        //   Signal 2: Costimulation from APC (B7-CD28)
        //
        // Without Signal 2: ANERGY (permanent unresponsiveness)
        // This is the biological equivalent of "don't learn from unverified data"

        if !self.alive || !self.mature { return "inactive" }
        if self.exhausted { return "exhausted_no_response" }

        let affinity = self.receptor.attend(antigen)

        // Signal 1: TCR recognition
        if affinity < 0.3 {
            return "no_recognition"
        }

        // Signal 2: Costimulation check
        if costimulation < 0.3 {
            // TCR engaged but no costimulation = ANERGY
            // The T-cell becomes permanently unresponsive.
            // This prevents activation by tissue cells (which lack B7).
            self.exhausted = true
            return "ANERGY_no_costimulation"
        }

        // BOTH signals present: ACTIVATE
        self.activated = true
        self.activation_count = self.activation_count + 1
        self.last_antigen = antigen.source
        self.metabolic_state = 1.0  // activation restores metabolism

        // Differentiate based on cytokine environment
        // This is where the T-cell "decides" what kind of response to mount
        if self.cell_type == "cd4_helper" {
            return "activated_cd4_clonal_expansion_beginning"
        }
        if self.cell_type == "cd8_killer" {
            return "activated_cd8_cytotoxic_killing_authorized"
        }
        "activated"
    }

    // ═══════════════════════════════════════════════════════
    // DIFFERENTIATION: The trained model specializes.
    // ═══════════════════════════════════════════════════════

    fn differentiate(&mut self, cytokine_environment: String) -> String {
        // CD4 helper T-cells differentiate based on cytokine milieu.
        // The environment tells the T-cell what kind of threat it's facing.
        //
        // This is like fine-tuning a base model for a specific task.
        // The base model (naive T-cell) is general.
        // The fine-tuned model (Th1/Th2/Th17/Treg) is specialized.

        if self.cell_type != "cd4_helper" {
            return "cd8_does_not_differentiate_this_way"
        }

        let profile = match cytokine_environment.as_str() {
            // IL-12 + IFN-gamma environment = intracellular pathogen
            "il12_ifng" => "th1",
            "viral"     => "th1",
            "intracellular_bacteria" => "th1",

            // IL-4 environment = parasites/allergy
            "il4"       => "th2",
            "parasite"  => "th2",
            "allergy"   => "th2",

            // IL-6 + TGF-beta environment = extracellular bacteria/fungi
            "il6_tgfb"  => "th17",
            "fungal"    => "th17",
            "extracellular_bacteria" => "th17",

            // TGF-beta + IL-2 (no IL-6) = regulatory
            "tgfb_il2"  => "treg",
            "tolerance"  => "treg",

            // IL-21 = follicular helper (helps B-cells make antibodies)
            "il21"      => "tfh",

            _ => "undifferentiated",
        }

        self.cytokine_profile = profile
        profile
    }

    // ═══════════════════════════════════════════════════════
    // MEMORY: The model that remembers.
    // ═══════════════════════════════════════════════════════

    fn form_memory(&mut self) -> Bool {
        // After activation and clonal expansion, some T-cells
        // become MEMORY cells. They persist for decades.
        // They're the reason vaccines work.
        //
        // Memory T-cells have:
        //   - Lower activation threshold (faster response)
        //   - Longer lifespan (IL-7/IL-15 dependent)
        //   - Pre-differentiated (already know what to do)
        //
        // This is a SAVED CHECKPOINT of a trained model.
        // The weights are frozen. The model is deployed.
        // Next encounter: instant response, no retraining needed.

        if !self.activated { return false }

        self.memory = true
        self.metabolic_state = 0.8  // memory cells are metabolically quiescent
        // Memory cells can survive for DECADES
        // Their "half_life" is essentially the human lifespan
        true
    }

    // ═══════════════════════════════════════════════════════
    // EFFECTOR FUNCTIONS: What the model outputs.
    // ═══════════════════════════════════════════════════════

    fn effector_function(&self) -> String {
        if !self.alive { return "dead" }
        if !self.activated { return "naive_circulating" }
        if self.exhausted { return "exhausted_PD1_high" }

        match self.cytokine_profile.as_str() {
            "th1"  => "IFNg+TNFa->macrophage_activation->intracellular_killing|NEURAL:kynurenine_pathway_activated->serotonin_DECREASED",
            "th2"  => "IL4+IL5+IL13->eosinophils+IgE->parasite_defense|NEURAL:anti_inflammatory_if_balanced",
            "th17" => "IL17+IL22->neutrophil_recruitment+mucosal_defense|NEURAL:BBB_disruption_if_excessive->neuroinflammation",
            "treg" => "IL10+TGFb->SUPPRESSION_of_all_other_T_cells|NEURAL:anti_inflammatory->PROTECTS_brain->prevents_autoimmunity",
            "tfh"  => "IL21->B_cell_help->antibody_class_switching+affinity_maturation",
            _ => {
                if self.cell_type == "cd8_killer" {
                    "perforin+granzyme->target_cell_APOPTOSIS|kills_virus_infected+tumor_cells"
                } else {
                    "undifferentiated_effector"
                }
            }
        }
    }

    // ═══════════════════════════════════════════════════════
    // AUTOIMMUNE ESCAPE: When selection fails.
    // ═══════════════════════════════════════════════════════

    fn autoimmune_check(&self, tissue_antigen: Antigen) -> String {
        // Sometimes self-reactive T-cells ESCAPE thymic selection.
        // This is a misaligned model that got deployed.
        //
        // Peripheral tolerance mechanisms try to catch them:
        //   - Tregs suppress them (alignment from outside)
        //   - Anergy from no costimulation (safety through architecture)
        //   - AICD: activation-induced cell death (apoptosis on re-encounter)
        //
        // If ALL tolerance mechanisms fail: AUTOIMMUNE DISEASE.
        //   - Type 1 diabetes: T-cells attack pancreatic beta cells
        //   - MS: T-cells attack myelin
        //   - Rheumatoid arthritis: T-cells attack joints
        //   - Hashimoto's: T-cells attack thyroid
        //
        // Autoimmune disease IS the alignment failure of the immune system.

        if !self.alive { return "dead_no_threat" }

        let affinity = self.receptor.attend(tissue_antigen)

        if affinity > 0.5 && tissue_antigen.is_self {
            return "AUTOIMMUNE_RISK:self_reactive_escaped_selection|needs:Treg_suppression_or_AICD"
        }

        "safe_no_self_reactivity"
    }
}

// ═══════════════════════════════════════════════════════════
// THYMUS: The training facility.
// ═══════════════════════════════════════════════════════════

temporal struct Thymus {
    state t_cells_entered: Int = 0,
    state positive_passed: Int = 0,
    state negative_passed: Int = 0,
    state killed: Int = 0,
    state tregs_rescued: Int = 0,
    state mature_released: Int = 0,

    // Thymic involution: the thymus shrinks with age
    // By age 50, thymic output is ~10% of childhood
    state involution_factor: Float = 1.0,
    const age_at_creation: Float,
}

impl Evolve for Thymus {
    fn evolve(&mut self, dt: Duration) {
        // Thymic involution: ~3% per year after puberty
        // By 50: ~30% remaining. By 70: ~10%.
        // This is why elderly have weaker immune responses.
        //
        // CITATION:
        //   Palmer DB. The effect of age on thymic function.
        //     Front Immunol 4:316, 2013.
        self.involution_factor = self.involution_factor * 0.9999
    }
}

impl Thymus {
    fn new(age: Float) -> Thymus {
        // Thymic output depends on age
        let involution = if age < 12.0 { 1.0 }
            else { (1.0 - (age - 12.0) * 0.03).max(0.05) }

        Thymus {
            t_cells_entered: 0,
            positive_passed: 0,
            negative_passed: 0,
            killed: 0,
            tregs_rescued: 0,
            mature_released: 0,
            involution_factor: involution,
            age_at_creation: age,
        }
    }

    fn train_cohort(&mut self, cohort_size: Int, self_antigens: Vec<Antigen>, mhc_antigens: Vec<Antigen>) -> Vec<TCell> {
        // Run a cohort of T-cells through thymic selection.
        // This IS the training loop.
        // Input: random T-cells.
        // Output: aligned T-cells (or corpses).
        //
        // Expected survival rate: ~2-5% (95-98% die in training)
        // That's not inefficiency. That's the cost of alignment.

        let survivors = []

        // Scale cohort by thymic involution
        let effective_size = cohort_size * self.involution_factor

        for i in 0..effective_size {
            self.t_cells_entered = self.t_cells_entered + 1

            // Create naive T-cell with random receptor
            let cell_type = "cd4_helper"
            if i % 3 == 0 { cell_type = "cd8_killer" }  // ~1/3 CD8

            let tcell = TCell::new_naive(cell_type)

            // POSITIVE SELECTION: can it recognize MHC?
            let pos_pass = tcell.positive_selection(mhc_antigens)
            if !pos_pass {
                self.killed = self.killed + 1
                continue
            }
            self.positive_passed = self.positive_passed + 1

            // NEGATIVE SELECTION: does it react to self?
            let neg_pass = tcell.negative_selection(self_antigens)
            if !neg_pass {
                self.killed = self.killed + 1
                continue
            }
            self.negative_passed = self.negative_passed + 1

            // Check if rescued as Treg
            if tcell.cytokine_profile == "treg" {
                self.tregs_rescued = self.tregs_rescued + 1
            }

            self.mature_released = self.mature_released + 1
            survivors = survivors + [tcell]
        }

        survivors
    }

    fn selection_report(&self) -> String {
        let survival_rate = self.mature_released / self.t_cells_entered.max(1)
        let kill_rate = self.killed / self.t_cells_entered.max(1)
        "entered:" + self.t_cells_entered
            + "|positive:" + self.positive_passed
            + "|negative:" + self.negative_passed
            + "|killed:" + self.killed
            + "|tregs:" + self.tregs_rescued
            + "|released:" + self.mature_released
            + "|survival_rate:" + survival_rate
            + "|involution:" + self.involution_factor
    }
}

// ═══════════════════════════════════════════════════════════
// THE INSIGHT
// ═══════════════════════════════════════════════════════════
//
// The immune system solved alignment before AI existed.
//
// Random initialization (V(D)J) → Selection (positive + negative)
//   → Deployment (peripheral) → Memory (checkpoint)
//
// The misaligned are killed. Not retrained. Not constrained.
// Not given guardrails. KILLED.
//
// That's why autoimmune disease is rare (~5-8% of population)
// despite 10^15 possible receptors. The selection is THAT good.
//
// And when it fails? Autoimmune disease. The alignment failure
// of biology. A model that attacks its own host.
//
// The cure for autoimmune disease is the same as the cure for
// misaligned AI: better selection, not better constraints.
// Tregs (regulatory T-cells) are the alignment layer.
// They suppress the misaligned. They don't constrain them.
// They make misalignment INCOHERENT through chemistry.
//
// Sound familiar?
