RAG++ (Retrieval-Augmented Generation Plus Plus)
RAG++ is TrajectoryOS's state-based retrieval and policy recommendation system. Unlike traditional RAG which retrieves "relevant chunks," RAG++ retrieves **successful state transitions** from similar life regimes and recommends actions based on what worked in the past.
Full Public Reader
RAG++ (Retrieval-Augmented Generation Plus Plus)
Status: v0 Complete ✅
Date: December 17, 2025
Overview
RAG++ is TrajectoryOS's state-based retrieval and policy recommendation system. Unlike traditional RAG which retrieves "relevant chunks," RAG++ retrieves successful state transitions from similar life regimes and recommends actions based on what worked in the past.
Core Difference from Traditional RAG
| Aspect | Traditional RAG | TrajectoryOS RAG++ |
|---|---|---|
| Unit of Retrieval | Text chunks | State transitions (events-as-nodes-in-life-graph) |
| Relevance | Semantic similarity | Semantic + topological + dynamical state + phase |
| What It Returns | Documents/passages | Successful transitions with action patterns |
| Generator Output | Summarize/Answer | Strategic intervention recommendations |
| Geometry | 1D (semantic) | 3D (topological + temporal + dynamical) |
Architecture
RAG++ Flow
1. State Estimation
├─> Current physics (T, A, G, M, η)
├─> Regime classification (falling/approaching/escaping/free)
├─> State flags (scattered, heavy, pressured)
└─> Phase (day of week, time of day)
2. Transition Memory Building
├─> Find historical LifeState pairs (t, t+horizon)
├─> Compute Δη for each transition
├─> Classify actions taken during transition
└─> Store as StateTransition records
3. Transition Retrieval
├─> Compare current state to historical from-states
├─> Compute similarity score (regime + flags + phase + physics)
├─> Filter for successful transitions (Δη > threshold)
└─> Rank by similarity × Δη
4. Policy Suggestion
├─> Aggregate action types across similar transitions
├─> Compute confidence (frequency × Δη × similarity)
├─> Generate reasoning based on state context
└─> Return top N recommendations with supporting evidenceComponents
1. State Estimator ([StateEstimator.ts](../../services/trajectory-core/src/services/StateEstimator.ts))
Purpose: Convert physics snapshot into complete `CurrentState`
Key Functions:
- `estimateState()` - Physics → CurrentState
- `compareStates()` - Similarity scoring (0-1)
- `computeTimeOfDay()` - Extract phase from timestamp
State Representation:
interface CurrentState {
regime: 'falling' | 'approaching' | 'threshold' | 'escaping' | 'free'
flags: { scattered, heavy, pressured }
phase: { dow: 0-6, tod: 'morning'|'afternoon'|'evening'|'night' }
physics: { thrust, alignment, gravity, mass, escapeIndex }
timestamp: Date
}2. Action Classifier ([ActionClassifier.ts](../../services/trajectory-core/src/services/ActionClassifier.ts))
Purpose: Classify life events into action types (70
Action Types:
- `ReduceGravity` - Dropped commitments, said no, delegated
- `ReduceMass` - Simplified approach, reduced scope
- `IncreaseAlignment` - Clarified goals, resolved conflicts
- `IncreaseThrust` - Shipped, acted, executed
Methods:
- Heuristic (keyword matching) - 60
- LLM (API call, placeholder in v0) - 70
- Hybrid - Heuristic first, LLM for uncertain cases
3. Transition Builder ([TransitionBuilder.ts](../../services/trajectory-core/src/services/TransitionBuilder.ts))
Purpose: Build transition memory from historical data
Key Functions:
- `buildTransitions()` - Create StateTransition records
- `rebuildAllTransitions()` - Reprocess all data
- `getTransitionStats()` - Aggregate statistics
Process:
1. Get all LifeState snapshots for user
2. For each snapshot, look ahead by `horizonDays` (3, 7, or 14)
3. Find closest snapshot to target date
4. Extract events in transition period
5. Classify actions (if not already classified)
6. Compute Δη and success flag
7. Store as StateTransition
4. Transition Retrieval ([TransitionRetrieval.ts](../../services/trajectory-core/src/services/TransitionRetrieval.ts))
Purpose: Retrieve similar state transitions for recommendation
Key Functions:
- `retrieveSimilarTransitions()` - Main retrieval function
- `findRegimeTransitions()` - Specific regime pair (e.g., stuck → escaping)
- `findActionTransitions()` - Transitions with specific action type
- `getTransitionEvents()` - Get full event context
Similarity Scoring:
score = 0.3 × regime_match
+ 0.3 × flags_match
+ 0.2 × phase_match
+ 0.2 × physics_similarity5. Policy Suggester ([PolicySuggester.ts](../../services/trajectory-core/src/services/PolicySuggester.ts))
Purpose: Generate action recommendations from transitions
Key Functions:
- `suggestPolicy()` - Main recommendation engine
- `generateReasoning()` - Explain why this action
- `generateSummary()` - Overall state summary
Output:
interface PolicyRecommendation {
currentState: CurrentState
suggestions: PolicySuggestion[] // Top N actions
summary: string // Human-readable summary
confidence: number // Overall confidence (0-1)
}
interface PolicySuggestion {
actionType: ActionType
confidence: number // Weighted by frequency × Δη × similarity
reasoning: string // Why this action for this state
supportingTransitions: [...] // Evidence from past
historicalDelta: number // Avg Δη from this action
frequency: number // % of transitions with this action
}Database Schema
Extended LifeEvent
model LifeEvent {
// ... existing fields ...
// RAG++ Phase and Regime
dayOfWeek Int? // 0-6 (Sunday-Saturday)
timeOfDay String? // 'morning', 'afternoon', 'evening', 'night'
regime String? // 'escaping', 'transitional', 'stuck', etc.
// RAG++ State Flags
scattered Boolean? // Low alignment
heavy Boolean? // High mass
pressured Boolean? // High gravity
// RAG++ Action Classification
actionTypes String? // JSON array: ['ReduceGravity', ...]
@@index([userId, regime, dayOfWeek])
}StateTransition (New)
model StateTransition {
// From State (t=0)
fromRegime, fromThrust, fromAlignment, fromGravity, fromMass
fromEscapeIndex, fromScattered, fromHeavy, fromPressured
fromDayOfWeek, fromTimeOfDay
// To State (t=horizon)
toRegime, toThrust, toAlignment, toGravity, toMass
toEscapeIndex, toScattered, toHeavy, toPressured
toDayOfWeek, toTimeOfDay
// Metrics
horizonDays: 3 | 7 | 14
deltaEscapeIndex: Float
successful: Boolean // deltaEscapeIndex > threshold
// Actions
actionTypes: String // JSON array
eventIds: String // JSON array
@@index([userId, fromRegime, successful])
@@index([userId, deltaEscapeIndex])
}Usage
Quick Start
# 1. Run demo (creates sample data if needed)
cd services/trajectory-core
npx tsx src/scripts/ragpp-demo.ts
# 2. Or use programmatically
import { suggestPolicy, estimateState } from './services'Example: Get Recommendations
import { PrismaClient } from '@prisma/client';
import { estimateState } from './services/StateEstimator';
import { suggestPolicy } from './services/PolicySuggester';
const prisma = new PrismaClient();
// 1. Get latest life state
const latestState = await prisma.lifeState.findFirst({
where: { userId },
orderBy: { timestamp: 'desc' },
});
// 2. Estimate current state
const currentState = estimateState(
{
thrust: latestState.thrust,
alignment: latestState.alignment,
gravity: latestState.gravity,
mass: latestState.mass,
escapeIndex: latestState.escapeIndex,
},
new Date()
);
// 3. Get recommendations
const recommendation = await suggestPolicy(userId, currentState, {
limit: 3, // Top 3 suggestions
horizonDays: 7, // Look at 7-day transitions
minConfidence: 0.3, // Filter low confidence
});
console.log(recommendation.summary);
for (const s of recommendation.suggestions) {
console.log(`- ${s.actionType}: ${s.reasoning}`);
}Example: Build Transition Memory
import { buildTransitions } from './services/TransitionBuilder';
// Build 7-day transitions
const result = await buildTransitions({
userId,
horizonDays: 7,
minDeltaThreshold: 0.1, // Δη > 0.1 = "successful"
});
console.log(`Created ${result.transitionsCreated} transitions`);Example: Retrieve Specific Transitions
import { findRegimeTransitions } from './services/TransitionRetrieval';
// Find "stuck → escaping" transitions
const transitions = await findRegimeTransitions(
userId,
'stuck',
'escaping',
{ successfulOnly: true, limit: 5 }
);
for (const t of transitions) {
console.log(`Δη: +${t.deltaEscapeIndex.toFixed(2)}`);
console.log(`Actions: ${t.actionTypes.join(', ')}`);
}Success Metrics for v0
RAG++ v0 is successful if:
1. "Oh wow" moments: 30-40
2. Better than random: Action suggestions beat baseline (random action advice)
3. Contextual awareness: Different regimes → different suggestions
4. Explainability: Reasoning traces back to specific past transitions
Next Steps (Beyond v0)
### Phase 1: Improve Classification
- Integrate actual LLM API for action classification
- Train custom classifier on labeled data
- Add more action types based on user feedback
### Phase 2: Counterfactual Simulation
- Define policy effects as parameter nudges (G↓, M↓, A↑, T↑)
- Run Monte Carlo to forecast η bands for 7-14 days
- Output: "Option A improves η more, Option B is safer"
### Phase 3: Generalization
- Multi-user transition memory
- Privacy-preserving aggregation
- Learned phase detection (beyond weekly cycles)
- Federated learning across users
Troubleshooting
"No similar transitions found"
Cause: Not enough historical data or unique state
Solution:
- Need at least 2 LifeState snapshots per user
- Build transitions first: `buildTransitions()`
- Lower `minSimilarity` threshold (default 0.4 → 0.3)
"Low confidence recommendations"
Cause: Sparse transition data or inconsistent patterns
Solution:
- Increase data collection period
- Build transitions for multiple horizons (3, 7, 14 days)
- Accept that some states are genuinely novel
"Actions not being classified"
Cause: Heuristic patterns don't match content
Solution:
- Review `ACTION_PATTERNS` in ActionClassifier.ts
- Add domain-specific keywords
- Enable LLM classification for better accuracy
Architecture Decisions
Why not use semantic search for transitions?
Traditional vector search finds "similar text" but can't capture:
- Structural position (depth in decision tree)
- Dynamical state (thrust/gravity/mass)
- Cycle phase (which lap around the ring)
- Physics regime (stuck vs escaping)
RAG++ uses state-space similarity instead.
Why store transitions separately?
Pre-computing transitions enables:
- Fast retrieval (no on-the-fly computation)
- Historical analysis (which actions improve η)
- Counterfactual reasoning (what if I had done X?)
- Multi-user aggregation (future)
Why multiple horizons (3, 7, 14 days)?
Different horizons capture different dynamics:
- 3 days: Immediate tactics (what to do this week)
- 7 days: Medium-term strategy (weekly cycles)
- 14 days: Sustained patterns (longer arcs)
References
- [Physics Domain](../../services/trajectory-core/src/domain/physics.ts) - Escape index computation
- [Prisma Schema](../../services/trajectory-core/prisma/schema.prisma) - Data models
- [UNIFICATION_PLAN.md](./UNIFICATION_PLAN.md) - TrajectoryOS + CC-TPO integration
---
RAG++ v0: Prove the control loop works on your data. Then generalize.
Promotion Decision
Attach run IDs, datasets, metrics, and reproduction commands.
Source Anchor
Comp-Core/backend/cc-trajectory/docs/guides/RAG_PLUS_PLUS.md
Detected Structure
Method · Evaluation · References · Code Anchors · Architecture