PortiaSynapse: A Cognitive Spider Architecture for DKL Navigation
Corben Sorenson — original collaborator credits preserved in the manuscript
December 23, 2024
← Corben Papers and Architecture Sources
This page publishes Corben Sorenson’s original source manuscript so readers can inspect the ideas that preceded or informed the living book. The text may contain historical terminology, claims, confidence, citations, or implementation status that the book later narrows, revises, tests, or rejects. Publication here establishes provenance and access—not correctness, novelty, replication, or support-state promotion.
Publication and provenance
| Field | Record |
|---|---|
| Source ID | portia_synapse |
| Source class | technical_whitepaper |
| Library class | project_paper_lineage |
| Manuscript date | 2024-12-23 |
| Inventory updated | Not separately recorded |
| Exact published-source SHA-256 | 79501f3b5f1d068a9c2dfd285f9b502eaedcb84663ef4b070638311554092ce6 |
| Exact published-source bytes | 60,274 |
| Exact source text | Download/view the tracked Markdown source |
| Book’s source note | Read the bounded mining note |
| Authorship and collaborator credits | Preserved from the exact original manuscript; this library wrapper does not replace or simplify them. |
| Rights | No new license grant. Corben Sorenson’s rights are reserved; collaborator, quotation, source-title, and third-party rights remain with their holders. |
Current publication boundary. Successor architecture manuscript to SpiderSynapse. Historical test and implementation statements are reproduced from the source and are not independently revalidated by publication.
HTML presentation note. The HTML page normalizes line endings and trailing whitespace, preserves explicit Markdown hard breaks, and demotes manuscript headings beneath the page title. The digest above applies to the linked exact source text, not to this presentation wrapper.
Where this paper enters the living book
Durable Semantic Memory and Knowledge Lattices, Routing Heads and Specialist Cores, Governed Deliberation and Test-Time Scaling, Benchmark Ratchets and Anti-Goodhart Evidence, Policy Optimization and Learning from Feedback
Original manuscript
PortiaSynapse: A Cognitive Spider Architecture for DKL Navigation
Version: 1.1.0 Last Updated: 2024-12-23 Status: ✅ Implemented and Tested (24 tests passing) Named After: Portia jumping spiders - renowned for exceptional problem-solving, planning, and cognitive flexibility Target: Replace broken SpiderSynapse with trainable architecture deeply integrated with TreeLLM Implementation: treellm-navigator/src/portia_synapse.rs (~2535 lines)
Abstract
PortiaSynapse is TreeLLM’s next-generation “thinking spider” architecture, designed to replace the broken SpiderSynapse while deeply integrating with the Dynamic Knowledge Lattice (DKL). Unlike SpiderSynapse’s overly complex multi-hypothesis approach that failed to train (loss stuck at 0.57, accuracy oscillating 68-70%), PortiaSynapse takes inspiration from the actual cognitive strategies of Portia spiders:
- Scout Before Commit - Plan DKL traversal routes before executing (like Portia’s detour planning)
- Selective Attention - Focus on relevant nodes and edges, ignore distractions
- Working Memory - Accumulate facts across multi-hop graph traversal
- Trial-and-Error Refinement - Lightweight iterative improvement that actually trains
- Calibrated Confidence - Know when to ask for help or trigger knowledge lookup
Core Integration Points
PortiaSynapse is designed specifically for TreeLLM’s unique architecture:
| TreeLLM Component | PortiaSynapse Integration |
|---|---|
| DKL (Dynamic Knowledge Lattice) | Navigates 59+ edge types, reads DklSnapshots |
| 128-bit HLSH Coordinates | Predicts next coordinates for graph traversal |
| RichContext (512-dim) | Native input format with all 5 components |
| ReasoningChain | Produces multi-hop chains for explainability |
| EdgeType Prediction | Predicts which edge to follow (not just coordinates) |
| generate_smart() | Drop-in replacement for DklAwareSynapse |
| Adversary System | Outputs calibrated confidence for adversarial debate |
The key insight is that simplicity enables training. PortiaSynapse starts with a trainable core and adds complexity only where proven beneficial through phased validation.
1. Why Portia?
1.1 The Portia Spider: Nature’s Cognitive Champion
Portia spiders (family Salticidae) are remarkable for their cognitive abilities despite having brains smaller than a pinhead (~600,000 neurons). Research has documented:
| Capability | Description | DKL Traversal Analogy |
|---|---|---|
| Detour Planning | Plans 30+ body-length routes while prey is out of sight | Plan multi-hop DKL paths before executing |
| Working Memory | Maintains prey location in memory during complex detours | Accumulate facts in memory during reasoning |
| Selective Attention | Focuses on relevant stimuli, ignores distractions | Attend to relevant edges (DefinitionPart, HasAttribute) |
| Trial-and-Error | Iteratively refines approach when blocked | Lightweight refinement with gradient-friendly design |
| Numerical Cognition | Represents exact small numbers (1-3) precisely | Precise 128-bit coordinate prediction |
| Path Integration | Vector-based navigation in 3D space | Navigate 128-bit semantic coordinate space |
1.2 Why Not SpiderSynapse?
SpiderSynapse failed because of premature complexity:
| Problem | SpiderSynapse Design | PortiaSynapse Solution |
|---|---|---|
| Gradient Dilution | 4 hypotheses × 3 iterations = 12 paths | Single path with 2 refinements |
| Hypothesis Collapse | 4 hypotheses → identical outputs | No hypotheses (single path) |
| Post-Norm Architecture | LayerNorm after operations | Pre-Norm (proven more stable) |
| Complex Multi-Aspect Encoder | 3 separate encoders (semantic, structural, edge) | Unified encoder respecting RichContext |
| Training Never Validated | Built full 4.8M param architecture first | Phased training, verify each component |
| Loss Stuck at 0.57 | 20+ mins training, no improvement | Built-in diagnostics to catch issues |
1.3 How PortiaSynapse Fits TreeLLM
PortiaSynapse is designed as a drop-in replacement for DklAwareSynapse:
// Current DklAwareSynapse usage in generate_smart():
let result = synapse.forward(&rich_context, depth)?;
let coord = synapse.predict_coord(&context)?;
let edge = synapse.predict_edge(&context)?;
// PortiaSynapse has identical interface:
let result = portia.forward(&rich_context, depth)?;
let coord = portia.predict_coord(&context)?;
let edge = portia.predict_edge(&context)?;It consumes the same RichContext (512-dim) and produces the same outputs: - Coordinate logits (128-bit): Next DKL node to visit - Edge type logits (64 types): Which edge to follow - Confidence scalar: Calibrated for adversary debate
2. Architecture Overview
2.1 Design Principles
- Train First, Optimize Later - Every component must demonstrate decreasing loss before adding more
- RichContext Native - Designed for TreeLLM’s 512-dim context (coord + content + edges + neighbors + modulation)
- Pre-Norm Architecture - LayerNorm before operations for stable gradients (not after)
- Residual Everything - Skip connections on every major block = gradient highways
- DKL-Aware - Understands edge types, not just coordinates
2.2 High-Level Architecture
┌──────────────────────────────────────────────────────────────────────────────┐
│ PortiaSynapse │
│ "The Thinking Spider on the DKL" │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ RichContext (512-dim) │
│ ┌─────────┬─────────┬──────────┬─────────────┬────────────┐ │
│ │CoordBits│Content │EdgeDist │NeighborSum │ Modulation │ │
│ │ (128) │ (128) │ (64) │ (128) │ (64) │ │
│ └────┬────┴────┬────┴────┬─────┴──────┬──────┴─────┬──────┘ │
│ └─────────┴─────────┴────────────┴────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Scout Module (Route Planning - like Portia) │ │
│ │ • Pre-Norm LayerNorm │ │
│ │ • Linear (512 → 512) + GELU │ │
│ │ • Selective Gate (which context dims matter?) │ │
│ │ • Residual: output = input + gated_transform │ │
│ └────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ ┌───────────┐ │
│ │ Focus Module (Selective Attention - like Portia) │◄──►│ Working │ │
│ │ • Pre-Norm + Single-head self-attention │ │ Memory │ │
│ │ • Attends to which parts of context matter most │ │ (512-d) │ │
│ │ • Gated memory update (accumulate facts) │ └───────────┘ │
│ │ • Residual connection │ │
│ └────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Refinement Module (Trial-and-Error) │ │
│ │ • 2 iterations only (not 3 - less gradient dilution) │ │
│ │ • Each: Pre-Norm → FFN(512→1024→512) → Residual │ │
│ │ • Total refinement params: ~2M │ │
│ └────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ Coordinate │ │ Edge Type │ │ Confidence │ │
│ │ Head │ │ Head │ │ Head │ │
│ │ (4-layer MLP) │ │ (2-layer MLP) │ │ (2-layer MLP) │ │
│ │ → 128 bits │ │ → 64 types │ │ → 1 scalar │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ │
│ │
│ Outputs: │
│ • next_coord: u128 (which DKL node to visit) │
│ • edge_type: EdgeType (which edge to follow - from 59+ types) │
│ • confidence: f32 (for adversary debate threshold) │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
2.3 Data Flow During Inference
Query "What color is the sky?"
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 1. HLSH hashes query → start_coord (128-bit) │
│ 2. DKL lookup: get node at start_coord → "sky" node │
│ 3. Build RichContext from DKL neighborhood: │
│ - coord_bits: 128 bits of start_coord │
│ - content_embed: char-level hash of "sky" │
│ - edge_dist: which edges exist (HasAttribute:0.5, Hypernym:0.3, ...) │
│ - neighbor_summary: average embedding of neighbors │
│ - modulation: question mark detected → [1.0, 0.0, 0.3, ...] │
│ 4. PortiaSynapse.forward(rich_context) → predicts: │
│ - next_coord → "blue" node │
│ - edge_type → HasAttribute │
│ - confidence → 0.92 │
│ 5. Follow edge: sky --HasAttribute--> blue │
│ 6. Construct answer: "The sky is blue." │
└─────────────────────────────────────────────────────────────────────────────┘
3. Component Details
3.1 Scout Module (Route Planning)
Inspired by Portia’s ability to plan detours of 30+ body lengths before executing them. The Scout Module “looks ahead” to determine which aspects of the RichContext are most relevant for this query type.
/// Scout Module: Plan the traversal route
///
/// Like Portia scanning the environment before jumping,
/// this module determines which parts of the context matter.
pub struct ScoutModule {
pre_norm: LayerNorm, // Normalize BEFORE processing (Pre-Norm)
transform: Linear, // 512 → 512
gate: Linear, // 512 → 512 (sigmoid → selective)
}
impl ScoutModule {
pub fn forward(&self, x: &Tensor) -> candle_core::Result<Tensor> {
// Pre-Norm: normalize first for stable gradients
let normed = layer_norm(x, &self.pre_norm)?;
// Transform with GELU (smooth non-linearity)
let transformed = self.transform.forward(&normed)?.gelu_erf()?;
// Selective gate: learn which dimensions matter
// Like Portia's selective attention to relevant stimuli
let gate = self.gate.forward(&normed)?.sigmoid()?;
// Gated output with residual connection
let gated = transformed.mul(&gate)?;
x.add(&gated) // Residual: always preserve input gradient path
}
}Key Design Choices: - Pre-Norm: LayerNorm before linear, not after (proven more stable - see Xiong et al. 2020) - Selective Gating: Learns which of the 512 dimensions matter for this query (Portia’s selective attention) - Residual: Always add input back = gradient highway to early layers
Parameters: ~525K (512×512×2)
3.2 Focus Module (Selective Attention)
Single-head self-attention that focuses on the most relevant parts of the RichContext. Unlike SpiderSynapse’s 8-head cross-hypothesis attention (which caused gradient issues), this is simple, interpretable, and trainable.
The key insight: we’re not doing sequence attention - we’re learning which of the 512 context dimensions are most relevant for this query.
/// Focus Module: Selective attention over context dimensions
///
/// Implements Portia's selective attention - focus on relevant stimuli
/// while ignoring distractions. Also maintains working memory.
pub struct FocusModule {
pre_norm: LayerNorm,
qkv_proj: Linear, // 512 → 1536 (Q, K, V concatenated)
out_proj: Linear, // 512 → 512
memory_gate: Linear, // 1024 → 512 (combines attended + memory)
}
impl FocusModule {
pub fn forward(&self, x: &Tensor, memory: &mut Tensor) -> candle_core::Result<Tensor> {
// Pre-Norm
let normed = layer_norm(x, &self.pre_norm)?;
// Project to Q, K, V
let qkv = self.qkv_proj.forward(&normed)?;
let (q, k, v) = qkv.chunk(3, 1)?; // Split on dim 1
// Scaled dot-product attention over context dimensions
// This learns which parts of RichContext matter most
let scale = (512.0_f32).sqrt();
let attn_scores = q.matmul(&k.t()?)?.div(&scale)?;
let attn_weights = candle_nn::ops::softmax(&attn_scores, 1)?;
let attended = attn_weights.matmul(&v)?;
// Gated memory update (accumulate facts like Portia's working memory)
let combined = Tensor::cat(&[&attended, memory], 1)?;
let gate = self.memory_gate.forward(&combined)?.sigmoid()?;
let new_memory = memory.mul(&gate.neg()?.add(&1.0)?)? // (1 - gate) * old
.add(&attended.mul(&gate)?)?; // + gate * new
*memory = new_memory;
// Output with residual
x.add(&self.out_proj.forward(&attended)?)
}
}Why Working Memory Matters: - Portia spiders maintain prey location in memory during complex detours - PortiaSynapse accumulates facts across multi-hop DKL traversal - Memory persists across forward passes during answer generation
Parameters: ~1M (512×512×4)
3.3 Refinement Module (Trial-and-Error)
Two lightweight refinement iterations (not three). Each iteration is a simple Pre-Norm → FFN → Residual block. This is the most parameter-heavy component, but gradients flow cleanly through it.
Why 2 Iterations, Not 3? - SpiderSynapse used 3 iterations × 4 hypotheses = 12 gradient paths → dilution - PortiaSynapse uses 2 iterations × 1 path = 2 gradient paths → clean signal - Research shows diminishing returns after 2 iterations for this task
/// Refinement Block: One iteration of trial-and-error improvement
pub struct RefinementBlock {
pre_norm: LayerNorm,
ffn_up: Linear, // 512 → 1024 (expansion)
ffn_down: Linear, // 1024 → 512 (projection)
}
impl RefinementBlock {
pub fn forward(&self, x: &Tensor) -> candle_core::Result<Tensor> {
let normed = layer_norm(x, &self.pre_norm)?;
let up = self.ffn_up.forward(&normed)?.gelu_erf()?;
let down = self.ffn_down.forward(&up)?;
x.add(&down) // Residual
}
}
/// Refinement Module: Two iterations of refinement
///
/// Like Portia's trial-and-error approach - try something,
/// observe the result, refine the approach.
pub struct RefinementModule {
blocks: [RefinementBlock; 2], // Only 2 iterations
}
impl RefinementModule {
pub fn forward(&self, x: &Tensor) -> candle_core::Result<Tensor> {
let mut h = x.clone();
for block in &self.blocks {
h = block.forward(&h)?;
}
Ok(h)
}
}Parameters: ~2M (512×1024×2 × 2 blocks)
3.4 Output Heads
Three output heads, each with Pre-Norm for stability. These are the same heads used by DklAwareSynapse for compatibility.
/// Coordinate Head: Predict next DKL node (128-bit coordinate)
///
/// 4-layer MLP matching RecursiveSynapse/DklAwareSynapse architecture.
/// Deep head is important for coordinate precision.
pub struct CoordinateHead {
pre_norm: LayerNorm,
h1: Linear, // 512 → 512
h2: Linear, // 512 → 512
h3: Linear, // 512 → 384
h4: Linear, // 384 → 384
out: Linear, // 384 → 128
}
/// Edge Type Head: Predict which edge to follow
///
/// Outputs logits over 64 edge type categories.
/// TreeLLM has 59+ edge types; we bucket to 64 for efficiency.
pub struct EdgeHead {
pre_norm: LayerNorm,
hidden: Linear, // 512 → 256
out: Linear, // 256 → 64
}
/// Confidence Head: Calibrated confidence for adversary debate
///
/// This is critical for TreeLLM's adversary system.
/// When confidence < threshold, trigger adversarial debate.
pub struct ConfidenceHead {
pre_norm: LayerNorm,
hidden: Linear, // 512 → 128
out: Linear, // 128 → 1
}| Head | Architecture | Output | TreeLLM Integration |
|---|---|---|---|
| Coordinate | 4-layer MLP (512→512→512→384→384→128) | 128 bits | DKL node lookup via coordinate |
| Edge Type | 2-layer MLP (512→256→64) | 64 logits | Choose edge type for traversal |
| Confidence | 2-layer MLP (512→128→1) | sigmoid scalar | Adversary debate threshold |
Parameters: ~600K (more accurate count than previous estimate)
3.5 Total Parameter Count
| Component | Parameters | % of Total |
|---|---|---|
| Scout Module | ~525K | 13% |
| Focus Module | ~1M | 25% |
| Refinement Module | ~2.1M | 52% |
| Output Heads | ~600K | 15% |
| Total | ~4.0M | 100% |
Comparison: - SpiderSynapse: 4.8M params (BROKEN - doesn’t train) - PortiaSynapse: 4.0M params (designed to train) - DklAwareSynapse: ~500K params (works but simpler)
The key difference is not size - it’s architecture. PortiaSynapse has: 1. Pre-Norm everywhere (stable gradients) 2. Single path (no hypothesis collapse) 3. 2 refinements (not 3 - less dilution) 4. Residual connections on everything (gradient highways)
4. Training Strategy
4.1 Phased Training (Learn to Walk Before Running)
Unlike SpiderSynapse which tried to train everything at once and failed, PortiaSynapse uses phased training to verify each component works before adding more complexity.
Phase 0: Coordinate-Only (Verify Learning - CRITICAL)
- What: Train Scout + Refinement + Coord Head only
- Why: Verify gradients flow through the architecture
- Target: Loss < 0.3 within 1000 steps
- Failure Mode: If loss doesn’t decrease, STOP and debug
- Batch Size: 1024 (larger than Spider’s 256)
Phase 1: Add Edge Prediction
- What: Add Edge Head, train on edge type prediction
- Why: Learning which edge to follow is critical for DKL navigation
- Target: Coord loss < 0.25, Edge accuracy > 80%
- Data: ReasoningChains from DKL traversal (same as DklAwareSynapse training)
Phase 2: Add Focus Module + Working Memory
- What: Add FocusModule with working memory
- Why: Multi-hop reasoning requires fact accumulation
- Target: Improvement on multi-hop benchmarks
Phase 3: Add Confidence Calibration
- What: Train confidence to predict accuracy
- Why: TreeLLM’s adversary system uses confidence thresholds
- Target: Expected Calibration Error (ECE) < 0.15
Phase 4: Full Pipeline Training - All losses active - Train on ReasoningChains from DKL - Run full benchmark suite - Target: Match or exceed DklAwareSynapse (93.8% on SOTA)
4.2 Training Hyperparameters
| Parameter | Value | Rationale |
|---|---|---|
| Batch Size | 1024 | Larger than Spider’s 256 (more stable gradients) |
| Learning Rate | VAV adaptive (default) | TreeLLM’s proven adaptive LR |
| Optimizer | AdamW (β1=0.9, β2=0.999, ε=1e-8) | Weight decay for regularization |
| Weight Decay | 0.01 | Prevent overfitting |
| Warmup Steps | 500 | Gradual LR increase (critical for stability) |
| Gradient Clipping | 1.0 | Prevent exploding gradients |
| Label Smoothing | 0.0 | DISABLED (caused Spider’s 0.56 plateau!) |
| Depth Parameter | 3 | Passed to forward() for context |
4.3 Training Data: ReasoningChains
PortiaSynapse trains on the same ReasoningChain data as DklAwareSynapse:
/// A step in a reasoning chain
pub struct ReasoningStep {
pub input_context: RichContext, // 512-dim context at current node
pub edge_type: EdgeType, // Edge we followed to get here
pub target_coord: u128, // Coordinate we reached
}
/// Full reasoning chain for multi-hop training
pub struct ReasoningChain {
pub query: String, // Original question
pub steps: Vec<ReasoningStep>, // Multi-hop path through DKL
pub answer: String, // Final answer content
}Training data is generated by: 1. Random DKL traversal (collect chains of 3-5 hops) 2. Q&A pairs with known paths (e.g., “What color is the sky?” → sky → blue) 3. Definition lookups (word → DefinitionPart edges → definition words)
4.4 Training Diagnostics (Built-In)
Critical lesson from SpiderSynapse: we didn’t know WHY it wasn’t training until too late.
Every PortiaSynapse training run logs:
pub struct TrainingDiagnostics {
// Per-layer gradient norms (detect vanishing/exploding)
pub grad_norms: HashMap<String, f32>,
// Activation statistics (detect dead neurons)
pub activation_stats: HashMap<String, (f32, f32)>, // (mean, std)
// Individual loss components (not just total)
pub coord_loss: f32,
pub edge_loss: f32,
pub conf_loss: f32,
// Confidence calibration bins
pub calibration_bins: Vec<(f32, f32)>, // (predicted, actual)
}Automatic Failure Detection: 1. If gradient norm < 1e-7 for any layer → “VANISHING GRADIENT DETECTED in {layer}” 2. If gradient norm > 100 for any layer → “EXPLODING GRADIENT DETECTED in {layer}” 3. If loss doesn’t decrease for 500 steps → “LOSS PLATEAU DETECTED - check architecture” 4. If activation std < 0.01 → “DEAD NEURONS DETECTED in {layer}”
5. Comparison with SpiderSynapse and DklAwareSynapse
| Aspect | SpiderSynapse | DklAwareSynapse | PortiaSynapse |
|---|---|---|---|
| Training Status | ❌ BROKEN | ✅ Works (93.8%) | ✅ Designed to train |
| Hypotheses | 4 parallel | 1 | 1 (no collapse) |
| Refinement Iterations | 3 | 0 (recurrent) | 2 (balanced) |
| Attention | 8-head cross-hyp | None | 1-head self |
| Normalization | Post-Norm | Layer-Norm | Pre-Norm |
| Parameters | 4.8M | ~500K | ~4.0M |
| Gradient Paths | 12 (4×3) | 1 | 2 |
| Working Memory | Yes (unused) | No | Yes (gated) |
| Training Approach | All-at-once | Single phase | Phased |
| Diagnostics | None | None | Built-in |
| Edge-Conditioned | Yes (complex) | Yes | Yes (simple) |
5.1 Why PortiaSynapse Will Train
Root causes of SpiderSynapse failure:
- Gradient Dilution: 4 hypotheses × 3 iterations = 12 gradient paths
- Each path gets 1/12th of the learning signal
- PortiaSynapse: 1 path × 2 iterations = clean signal
- Hypothesis Collapse: All 4 hypotheses converged to identical outputs
- PortiaSynapse: No hypotheses = no collapse possible
- Post-Norm Instability: LayerNorm after transformations
- PortiaSynapse: Pre-Norm (proven more stable - Xiong et al. 2020)
- No Validation: Built 4.8M param architecture without verifying training
- PortiaSynapse: Phased training validates each component
- Label Smoothing: Was set to 0.1, caused loss plateau at 0.56
- PortiaSynapse: Disabled (0.0) until proven needed
5.2 Why Not Just Use DklAwareSynapse?
DklAwareSynapse works (93.8% accuracy) but has limitations:
- No Working Memory: Can’t accumulate facts across hops
- Simple Recurrence: Single recurrent layer, not iterative refinement
- External Wrappers Needed: Requires
generate_smart()+ Adversary for quality - No Self-Correction: Can’t refine its own predictions internally
PortiaSynapse is the middle ground: - More sophisticated than DklAwareSynapse (memory, refinement, attention) - Simpler than SpiderSynapse (no hypotheses, fewer iterations) - Actually trainable (phased validation, built-in diagnostics)
6. Deep DKL Integration
PortiaSynapse is designed specifically for TreeLLM’s DKL. Here’s how it integrates:
6.1 Edge Type Awareness
TreeLLM has 59+ edge types. PortiaSynapse understands them:
// Edge types PortiaSynapse commonly predicts:
pub const IMPORTANT_EDGE_TYPES: &[(EdgeType, &str)] = &[
(EdgeType::DefinitionPart, "Word → Definition words (ordered)"),
(EdgeType::HasAttribute, "Entity → Properties (sky → blue)"),
(EdgeType::Hypernym, "Specific → General (dog → animal)"),
(EdgeType::Hyponym, "General → Specific (animal → dog)"),
(EdgeType::Synonym, "Word → Similar meaning"),
(EdgeType::Antonym, "Word → Opposite meaning"),
(EdgeType::Causes, "Event → Effect"),
(EdgeType::HasAnswer, "Question → Answer (Q&A pairs)"),
(EdgeType::InstanceOf, "Example → Category"),
(EdgeType::MarkovNext, "Word → Likely next word"),
];The Edge Head predicts which edge type to follow based on: - Query type (what/why/how/where/when) - Current node content - Available edges at current node
6.2 Answer Generation Pipeline
┌──────────────────────────────────────────────────────────────────────────┐
│ Query: "What causes rain?" │
├──────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. HLSH.hash_text("rain") → start_coord │
│ │
│ 2. DKL.get_node(start_coord) → "rain" node │
│ │
│ 3. Build RichContext: │
│ - coord_bits: 128 bits of start_coord │
│ - content_embed: hash("rain") │
│ - edge_dist: [Causes: 0.3, CausedBy: 0.4, HasAttribute: 0.2, ...] │
│ - neighbor_summary: avg(["water", "cloud", "precipitation"]) │
│ - modulation: [question:1.0, why:0.8, ...] │
│ │
│ 4. PortiaSynapse.forward(context) → { │
│ next_coord: coord_of("evaporation"), │
│ edge_type: CausedBy, │
│ confidence: 0.85 │
│ } │
│ │
│ 5. Follow edge: rain --CausedBy--> evaporation │
│ │
│ 6. Repeat from evaporation node (multi-hop): │
│ evaporation --Causes--> condensation │
│ condensation --Causes--> precipitation │
│ │
│ 7. Construct answer from collected facts: │
│ "Rain is caused by evaporation of water, which leads to │
│ condensation in clouds, resulting in precipitation." │
│ │
└──────────────────────────────────────────────────────────────────────────┘
6.3 Integration with generate_smart()
// In treellm-navigator/src/navigator.rs
pub fn generate_smart(&self, input: &str, config: Option<GenerationConfig>) -> GenerationResult {
// ... existing code ...
// PortiaSynapse can be used as drop-in replacement:
let context = RichContext::from_query(input, &self.hlsh, &self.storage);
// Forward pass through synapse
let output = self.portia_synapse.forward(&context, depth)?;
// Use predicted edge type to guide traversal
let next_node = self.storage.follow_edge(
current_coord,
output.edge_type,
output.next_coord
);
// If confidence is low, trigger adversary debate
if output.confidence < self.config.adversary_threshold {
return self.adversary.debate(input, initial_answer);
}
// ... continue generation ...
}6.4 Cognitive Mapping: Portia → PortiaSynapse
| Portia Behavior | PortiaSynapse Component | DKL Integration |
|---|---|---|
| Detour Planning | Scout Module | Plans which edges to follow before traversing |
| Selective Attention | Focus Module | Attends to relevant edge types for query |
| Working Memory | Memory tensor | Accumulates facts from multi-hop traversal |
| Trial-and-Error | Refinement Module | Refines predictions iteratively |
| Numerical Cognition | Coordinate Head | Predicts exact 128-bit DKL coordinates |
| Path Integration | Full architecture | Navigates semantic coordinate space |
| Knowing Uncertainty | Confidence Head | Triggers adversary debate when uncertain |
7. Implementation Roadmap
✅ Milestone 1: Minimal Viable Synapse (COMPLETE)
Goal: Prove the architecture can train at all
✅ Milestone 2: Add Edge Prediction (COMPLETE)
Goal: Learn to predict which edge to follow
✅ Milestone 3: Add Focus Module + Memory (COMPLETE)
Goal: Enable multi-hop reasoning with fact accumulation
✅ Milestone 4: Confidence Calibration (COMPLETE)
Goal: Know when to ask for help
🔄 Milestone 5: Full Integration (IN PROGRESS)
Goal: Drop-in replacement for DklAwareSynapse
8. Dimension Specification
8.1 Constants (Compatible with DklAwareSynapse)
// ═══════════════════════════════════════════════════════════════════════
// INPUT DIMENSIONS (MUST match DklAwareSynapse for drop-in replacement)
// ═══════════════════════════════════════════════════════════════════════
/// Total RichContext dimension
pub const RICH_CONTEXT_DIM: usize = 512;
/// 128-bit DKL coordinate encoded as ±1 floats
pub const COORD_BITS_DIM: usize = 128;
/// Content embedding from node text
pub const CONTENT_EMBED_DIM: usize = 128;
/// Edge type distribution (which edges exist)
pub const EDGE_DIST_DIM: usize = 64;
/// Average embedding of neighbor nodes
pub const NEIGHBOR_SUMMARY_DIM: usize = 128;
/// Modulation vector (question type, emotion, etc.)
pub const MODULATION_DIM: usize = 64;
// ═══════════════════════════════════════════════════════════════════════
// PORTIASYNAPSE-SPECIFIC DIMENSIONS
// ═══════════════════════════════════════════════════════════════════════
/// Main hidden dimension (same throughout)
pub const HIDDEN_DIM: usize = 512;
/// FFN expansion factor (512 → 1024 → 512)
pub const FFN_DIM: usize = 1024;
/// Number of refinement iterations (NOT 3 like SpiderSynapse)
pub const NUM_REFINEMENT_BLOCKS: usize = 2;
/// Number of edge type categories
pub const NUM_EDGE_TYPES: usize = 64;
/// Working memory dimension
pub const MEMORY_DIM: usize = 512;
// ═══════════════════════════════════════════════════════════════════════
// OUTPUT HEAD DIMENSIONS
// ═══════════════════════════════════════════════════════════════════════
/// Coordinate Head: 512 → 512 → 512 → 384 → 384 → 128
pub const COORD_HEAD_LAYERS: [(usize, usize); 5] = [
(512, 512), // h1
(512, 512), // h2
(512, 384), // h3
(384, 384), // h4
(384, 128), // output
];
/// Edge Head: 512 → 256 → 64
pub const EDGE_HEAD_LAYERS: [(usize, usize); 2] = [
(512, 256), // hidden
(256, 64), // output
];
/// Confidence Head: 512 → 128 → 1
pub const CONF_HEAD_LAYERS: [(usize, usize); 2] = [
(512, 128), // hidden
(128, 1), // output
];8.2 Tensor Shapes Through Forward Pass
┌────────────────────────────────────────────────────────────────────────┐
│ Layer │ Input Shape │ Output Shape │
├──────────────────────────┼──────────────────┼──────────────────────────┤
│ RichContext (input) │ - │ [batch, 512] │
│ ScoutModule │ [batch, 512] │ [batch, 512] │
│ FocusModule │ [batch, 512] │ [batch, 512] │
│ Working Memory │ [batch, 512] │ [batch, 512] (updated) │
│ RefinementBlock[0] │ [batch, 512] │ [batch, 512] │
│ RefinementBlock[1] │ [batch, 512] │ [batch, 512] │
│ CoordinateHead │ [batch, 512] │ [batch, 128] │
│ EdgeHead │ [batch, 512] │ [batch, 64] │
│ ConfidenceHead │ [batch, 512] │ [batch, 1] │
└────────────────────────────────────────────────────────────────────────┘
8.3 Parameter Count Breakdown
ScoutModule:
pre_norm: 512 × 2 = 1,024
transform: 512 × 512 + 512 = 262,656
gate: 512 × 512 + 512 = 262,656
Subtotal: = 526,336
FocusModule:
pre_norm: 512 × 2 = 1,024
qkv_proj: 512 × 1536 + 1536= 788,480
out_proj: 512 × 512 + 512 = 262,656
memory_gate: 1024 × 512 + 512 = 524,800
Subtotal: = 1,576,960
RefinementModule (2 blocks):
Block[0]:
pre_norm: 512 × 2 = 1,024
ffn_up: 512 × 1024 + 1024= 525,312
ffn_down: 1024 × 512 + 512 = 524,800
Block[1]: (same) = 1,051,136
Subtotal: = 2,102,272
CoordinateHead:
h1-h4 + out: ~600,000 = 600,000
EdgeHead:
hidden + out: ~140,000 = 140,000
ConfidenceHead:
hidden + out: ~66,000 = 66,000
═══════════════════════════════════════════════════
TOTAL PARAMETERS: ≈ 5,011,568 (~5.0M)
═══════════════════════════════════════════════════
Note: Slightly larger than SpiderSynapse (4.8M) but with better architecture. The Focus Module adds ~1.5M params for working memory capability.
9. Success Metrics
9.1 Training Metrics (Must Pass)
| Metric | Target | Failure Action |
|---|---|---|
| Phase 0 Loss | Decreases within 1000 steps | STOP - debug architecture |
| Gradient Norms | 1e-7 < norm < 100 | STOP - vanishing/exploding |
| Activation Std | > 0.01 | STOP - dead neurons |
| Loss Plateau | No plateau > 500 steps | STOP - check label smoothing |
9.2 Accuracy Metrics (Targets)
| Metric | Target | Current DklAwareSynapse |
|---|---|---|
| Coord Accuracy | > 85% | ~85% |
| Edge Accuracy | > 80% | ~80% |
| Confidence ECE | < 0.15 | N/A (no calibration) |
9.3 Benchmark Metrics (TreeLLM Suite)
| Benchmark | Target | Current Best | Notes |
|---|---|---|---|
| SOTA Benchmark | > 90% | 93.8% (DklAware) | Must match or exceed |
| HLE Benchmark | > 5% | 0% | Any improvement is good |
| Q&A Benchmark | > 80% | ~75% | Knowledge retrieval |
| Multi-hop Benchmark | > 70% | ~60% | Working memory helps here |
| MTP Benchmark | > 75% | ~70% | Multi-token prediction |
9.4 Performance Metrics
| Metric | Target | Rationale |
|---|---|---|
| Inference Latency | < 5ms | Interactive use |
| Memory Usage | < 50MB | Edge deployment |
| TLM File Size | < 25MB | Reasonable model size |
10. Future Extensions
IMPORTANT: Only pursue these AFTER PortiaSynapse is training and benchmarking well. Each extension must be validated with phased training before integration.
10.1 Multi-Hypothesis (Careful!)
If single-path works, cautiously add 2 hypotheses (not 4): - Use diversity loss to prevent collapse: diversity_loss = -mean(pairwise_cosine_distance(hypotheses)) - Verify training still works before adding more - Validation: Must maintain loss decrease rate
10.2 Graph Mamba Integration
Replace attention with Mamba-style selective state space: - Linear complexity O(n) instead of O(n²) - Better for long traversal sequences (>10 hops) - Selective scanning for relevant nodes - Reference: Gu & Dao (2023), Wang et al. (2024)
10.3 Adaptive Refinement
Learn when to stop refining: - Early exit if confidence > 0.95 (save compute) - More iterations for difficult queries (confidence < 0.5) - Dynamic computation allocation based on query complexity - Benefit: 2-3x speedup on easy queries
10.4 Conversation Memory
Extend working memory across conversation turns: - Retrieve relevant facts from previous turns - Update memory after successful predictions - Persistent across conversation (saved in TLM) - Integration: Works with TreeLLM’s conversation context system
10.5 Personality Matrix Integration
Modulate output based on personality: - Personality vector (64-dim) added to modulation component - Affects word choice via MarkovNext edge weights - Enables different “voices” for same knowledge - Integration: Uses TreeLLM’s existing personality matrix
11. References
Portia Spider Research
- Cross & Jackson (2016). “The execution of planned detours by spider-eating predators”
- Cross & Jackson (2017). “Representation of different exact numbers of prey by a spider-eating predator”
- Cross & Jackson (2019). “Portia’s capacity to decide whether a detour is necessary”
- Cross et al. (2020). “Arthropod Intelligence? The Case for Portia”
Modern Neural Architecture
- Gu & Dao (2023). “Mamba: Linear-Time Sequence Modeling with Selective State Spaces”
- Wang et al. (2024). “Graph Mamba: Towards Learning on Graphs with State Space Models”
- Xiong et al. (2020). “On Layer Normalization in the Transformer Architecture” (Pre-Norm)
Knowledge Graph Reasoning
- Mavromatis & Karypis (2024). “GNN-RAG: Graph Neural Retrieval for Large Language Model Reasoning”
Confidence Calibration
- Guo et al. (2017). “On Calibration of Modern Neural Networks”
- Northcutt et al. (2021). “Confident Learning: Estimating Uncertainty in Dataset Labels”
12. Changelog
| Version | Date | Changes |
|---|---|---|
| 0.1.0 | 2024-12-23 | Initial design based on Portia spider cognition research |
| 0.2.0 | 2024-12-23 | Deep DKL integration: RichContext, EdgeTypes, ReasoningChains |
| 0.2.1 | 2024-12-23 | Added answer generation pipeline, generate_smart() integration |
| 0.2.2 | 2024-12-23 | Detailed parameter counts, dimension specifications |
| 0.2.3 | 2024-12-23 | Enhanced training diagnostics, phased training details |
Appendix A: Why “Portia”?
The name honors Portia jumping spiders, particularly Portia fimbriata and Portia africana, which have been extensively studied for their remarkable cognitive abilities. Key findings:
Planning: Portia can plan detours of 30+ body lengths, maintaining prey location in working memory while the prey is out of sight.
Problem Solving: When confined, Portia uses trial-and-error to find escape routes, showing flexible problem-solving rather than fixed action patterns.
Numerical Cognition: Portia can represent exact small numbers (1, 2, 3) of prey items, showing expectancy violation when numbers change unexpectedly.
Selective Attention: Portia focuses on relevant stimuli while ignoring distractions, a key component of intelligent behavior.
Path Integration: Portia uses vector-based navigation to track prey location during complex 3D detours.
All of this with a brain of ~600,000 neurons - proof that intelligence doesn’t require massive parameter counts. PortiaSynapse aims to embody this principle: smart architecture beats brute-force scale.
Appendix B: Lessons from SpiderSynapse Failure
What Went Wrong
- Built Too Much Too Fast: Full 4-hypothesis, 3-iteration architecture before verifying training
- No Phased Validation: Never tested if simpler versions worked
- Post-Norm Architecture: Less stable gradient flow
- No Diagnostics: Couldn’t identify where gradients were dying
- Hypothesis Collapse: All 4 hypotheses produced identical outputs
What PortiaSynapse Does Differently
- Phased Development: Each component verified before adding more
- Pre-Norm: Proven more stable for deep networks
- Built-in Diagnostics: Gradient and activation monitoring
- Single Path First: No hypothesis collapse possible
- Fewer Iterations: 2 instead of 3 = cleaner gradient flow
The goal is not to build the most sophisticated architecture, but to build one that actually trains.
Appendix C: Implementation Details (v1.0.0)
Actual Parameter Counts
| Component | Parameters | Notes |
|---|---|---|
| InputProjection | ~262K | 512→512 linear |
| ScoutModule | ~525K | 2-layer MLP with gating |
| FocusModule | ~1.0M | Attention + gated memory update |
| RefinementModule | ~2.1M | 2 Pre-Norm FFN blocks (512→1024→512) |
| CoordinateHead | ~330K | 4-layer MLP → 128 bits |
| EdgeHead | ~66K | 2-layer MLP → 64 edge types |
| ConfidenceHead | ~33K | 2-layer MLP → 1 scalar |
| Total | ~5.0M | Trainable parameters |
Thread Safety
Working memory uses RwLock<Tensor> for thread-safe interior mutability, allowing: - &self in predict() and forward() methods - Safe concurrent access from multiple threads - Implements Send + Sync for trait requirements
Test Coverage
All 22 tests pass: - test_portia_creation - Basic instantiation - test_portia_forward - Forward pass produces valid outputs - test_portia_training - Single training step works - test_portia_phased_training - Phased training (coord-only, then full) - test_portia_end_to_end_training - Multi-epoch training with loss tracking - test_portia_evaluate_accuracy - Evaluation without training - test_portia_diagnostic_gradient_tracking - Gradient diagnostics - test_portia_chain_training - Multi-hop reasoning chain training - test_portia_save_load - Persistence to/from files - test_portia_working_memory_reset - Memory reset functionality - test_portia_synapse_registry - Registry-based creation - test_portia_full_training - Full training with confidence calibration (Phase 3+4) - test_portia_chain_full_training - Multi-hop chain training with full losses - test_portia_confidence_calibration - Confidence calibration improves over training - test_full_training_result_methods - FullTrainingResult helper methods - test_portia_ece_computation - ECE (Expected Calibration Error) computation - test_portia_edge_ece_computation - Edge type ECE computation - test_portia_train_full_from_batch - Training pipeline integration (raw batch input) - test_portia_train_full_from_batch_with_edges - Training pipeline with explicit edge types - test_portia_detection - UnifiedSynapse Portia detection methods - test_portia_full_training_via_unified - Full training through UnifiedSynapse - test_non_portia_full_training_fallback - Non-Portia synapses fall back correctly
Training Methods
| Method | Description | Returns |
|---|---|---|
train_step() |
Basic training (coord + edge loss) | (coord_loss, edge_loss) |
train_full() |
Full training with confidence calibration | FullTrainingResult |
train_chain() |
Multi-hop chain training (basic) | (coord_loss, edge_loss) |
train_chain_full() |
Multi-hop chain with full losses | FullTrainingResult |
train_full_from_batch() |
Pipeline-compatible full training (raw batch input) | FullTrainingResult |
train_full_from_batch_with_edges() |
Pipeline-compatible with explicit edge types | FullTrainingResult |
Training Pipeline Integration
PortiaSynapse is fully integrated with the training pipeline via UnifiedSynapse:
The training executor (treellm-server/src/training/executor.rs) automatically detects Portia synapses and uses full training with confidence calibration:
After training completes, the cognitive synapse benchmark is automatically run for Portia synapses, measuring: - Multi-hop reasoning accuracy - Edge type prediction accuracy - Coordinate ECE (Expected Calibration Error) - Edge ECE - Context retention accuracy - Bit-level accuracy
FullTrainingResult
pub struct FullTrainingResult {
pub coord_loss: f32, // Coordinate prediction loss (BCE)
pub edge_loss: f32, // Edge type prediction loss (CE)
pub conf_loss: f32, // Confidence calibration loss (MSE)
pub coord_accuracy: f32, // Coordinate prediction accuracy (>90% bit accuracy)
pub edge_accuracy: f32, // Edge type prediction accuracy
}
impl FullTrainingResult {
pub fn total_loss(&self) -> f32; // coord + 0.1*edge + 0.1*conf
pub fn is_healthy(&self) -> bool; // All losses finite and reasonable
}Usage
use treellm_navigator::portia_synapse::{PortiaSynapse, FullTrainingResult};
use treellm_navigator::synapse_trait::{SynapseCore, TrainableSynapse};
// Create synapse
let mut synapse = PortiaSynapse::new()?;
// Forward pass
let output = synapse.forward(&rich_context, depth)?;
println!("Predicted coord: {:?}", output.next_coord);
println!("Predicted edge: {:?}", output.edge_type);
println!("Confidence: {:.2}", output.confidence);
// Basic training
let (coord_loss, edge_loss) = synapse.train_step(&contexts, &target_coords, &target_edges, &mut optimizer, 0);
// Full training with confidence calibration (recommended)
let result = synapse.train_full(&contexts, &target_coords, &target_edges, &mut optimizer, 0);
println!("Total loss: {:.4}", result.total_loss());
println!("Coord accuracy: {:.2}%", result.coord_accuracy * 100.0);
// Via registry (plug-and-play)
use treellm_navigator::synapse_trait::{SynapseRegistry, init_default_synapses};
init_default_synapses();
let synapse = SynapseRegistry::create("portia")?;Modular Synapse Trait System
PortiaSynapse implements the new modular trait system (treellm-navigator/src/synapse_trait.rs):
| Trait | Purpose |
|---|---|
SynapseCore |
Core prediction, save/load, device info |
TrainableSynapse |
Coordinate and edge training |
ChainTrainable |
Multi-hop reasoning chain training |
DiagnosticSynapse |
Gradient norms, activation stats |
The SynapseRegistry allows creating synapses by name: - "portia" → PortiaSynapse (default) - "dklaware" → DklAwareSynapse
Navigator Integration
PortiaSynapse is integrated into the Navigator struct with dedicated methods:
// Navigator methods for PortiaSynapse
navigator.has_portia_synapse() // Check if available
navigator.portia_synapse() // Get reference
navigator.portia_synapse_mut() // Get mutable reference
navigator.set_portia_synapse(synapse) // Set synapse
navigator.load_portia_synapse_from_file(path) // Load from safetensors
// Generate using PortiaSynapse (falls back to generate_smart if unavailable)
let result = navigator.portia_generate_smart(input, config);The portia_generate_smart() method: 1. Falls back to generate_smart() if PortiaSynapse is not available 2. Tries deterministic engines first (math, logic) 3. Uses PortiaSynapse for multi-hop DKL traversal 4. Tracks reasoning path for explainability 5. Detects knowledge gaps and suggests lookups
ECE (Expected Calibration Error)
PortiaSynapse includes ECE computation for measuring calibration quality:
// Compute ECE for coordinate predictions
let ece_result = synapse.compute_ece(&contexts, &target_coords, 10);
println!("ECE: {:.4}", ece_result.ece); // Lower is better
println!("MCE: {:.4}", ece_result.mce); // Max calibration error
println!("Avg confidence: {:.2}", ece_result.avg_confidence);
println!("Avg accuracy: {:.2}", ece_result.avg_accuracy);
// Compute ECE for edge type predictions
let edge_ece = synapse.compute_edge_ece(&contexts, &target_edges, 10);ECE measures how well confidence predictions match actual accuracy: - ECE = 0.0: Perfect calibration (confidence = accuracy) - ECE > 0.1: Poor calibration (needs more training) - MCE: Maximum calibration error in any bin
Phased Training System
PortiaSynapse uses a 5-phase internal training progression that automatically adjusts which loss components are active:
pub enum PortiaTrainingPhase {
CoordOnly, // Phase 0: Only coordinate prediction (0-20% of training)
CoordAndEdge, // Phase 1: Coordinate + edge prediction (20-40%)
MultiHop, // Phase 2: Multi-hop chain training (40-60%)
ConfidenceCalibration, // Phase 3: Add confidence calibration (60-80%)
Full, // Phase 4: Full pipeline with all losses (80-100%)
}Phase-aware training methods:
// Automatically uses correct losses for current phase
let result = synapse.train_phased(&batch, &targets, &mut optimizer, depth);
// Chain training with phase awareness
let result = synapse.train_chain_phased(&chain, &mut optimizer, depth);
// Manual phase control
synapse.set_training_phase(PortiaTrainingPhase::Full);
synapse.advance_phase(); // Move to next phase
let phase = synapse.training_phase();Automatic phase progression in executor:
The training executor automatically advances Portia’s internal phase at 20% intervals: - 0-20%: Phase 0 (CoordOnly) - Learn coordinate prediction first - 20-40%: Phase 1 (CoordAndEdge) - Add edge type prediction - 40-60%: Phase 2 (MultiHop) - Enable multi-hop chain training - 60-80%: Phase 3 (ConfidenceCalibration) - Add confidence calibration - 80-100%: Phase 4 (Full) - All losses active
Portia Training Schedule
A dedicated training schedule is available for PortiaSynapse:
The Portia schedule includes: - All training data (foundations, reasoning, skills, knowledge, domains) - Automatic internal phase progression (0→4) - 50 epochs of coordinate alignment refinement (vs 20 for standard) - Automatic cognitive benchmark after training - TLM save with benchmark results
Edge Type Inference
When training from raw batches, PortiaSynapse infers edge types from context:
Inference logic: 1. Check edge_distribution field for non-zero values → use highest-weighted edge type 2. Fall back to modulation-based heuristics (high modulation → HasAttribute) 3. Default to MarkovNext for sequential/language modeling