# SaltyBot Social Memory Database (Issue #443)

Persistent SQLite-backed social knowledge system for maintaining person profiles, relationship history, and interaction statistics.

## Features

### 1. Person Profile Management
- **Person Records**: Name, relationship tier, custom greetings, notes, face embeddings
- **Relationship Tiers**:
  - **Stranger**: 0 encounters (default), cold greetings
  - **Regular**: 5+ encounters, familiar greetings
  - **Favorite**: 20+ encounters (or 80%+ positive interactions), warm greetings
- **Custom Greetings**: Tier-specific greeting strings
- **Face Embeddings**: Optional vector storage for face recognition
- **Notes**: Free-form observations about the person

### 2. Encounter Tracking
- **Encounter Recording**:
  - Timestamp, transcript of conversation, detected mood
  - Engagement score (0.0–1.0)
  - Positive/negative interaction flag
- **Automatic Tier Promotion**:
  - Encounter count-based: 5→regular, 20→favorite
  - Quality-based: 80%+ positive interactions required
  - Cooldown: 1 hour minimum between promotions
- **Statistics Aggregation**:
  - Total encounter count per person
  - Positive interaction ratio
  - Relationship score (computed from interactions)

### 3. ROS2 Service Interfaces

#### `/saltybot/social_memory/lookup`
```
Request:
  query_type: "id" | "name" | "recent"
  query_value: person_id | name_pattern | days_back

Response:
  found: boolean
  person_id: int32
  name: string
  relationship_tier: string
  relationship_score: float32 (0.0–1.0)
  interaction_count: int32
  custom_greetings: string[3]  # [stranger, regular, favorite]
  notes: string
  last_seen: Time
```

#### `/saltybot/social_memory/update`
```
Request:
  person_id: int32
  name: string
  relationship_tier: string
  custom_greetings: string[3]
  notes: string
  embedding: float32[]

Response:
  success: boolean
  message: string
  updated_person_id: int32
```

#### `/saltybot/social_memory/encounter`
```
Request:
  person_id: int32
  transcript: string
  mood: string
  engagement_score: float32
  positive_interaction: boolean

Response:
  success: boolean
  message: string
  encounter_id: int32
  tier_changed_to: string (or empty if no change)
```

#### `/saltybot/social_memory/stats`
```
Request:
  (empty)

Response:
  total_persons: int32
  total_encounters: int32
  favorites_count: int32
  regulars_count: int32
  strangers_count: int32
  database_size_mb: float32
  last_backup: Time
  database_path: string
```

### 4. Statistics Publishing
- **Topic**: `/saltybot/social_memory/stats_update` (std_msgs/String, JSON)
- **Frequency**: Configurable (default 60s)
- **Content**: Database statistics snapshot

### 5. Backup & Restore
- **Automatic Backups**: Gzipped snapshots stored in backup directory
- **Backup Tracking**: Recorded in database with timestamp and size
- **Manual Restore**: Restore from any backup file

## Database Schema

### `persons` Table
| Column | Type | Notes |
|--------|------|-------|
| person_id | INTEGER PRIMARY KEY | Auto-increment |
| name | TEXT UNIQUE | Person's name |
| embedding | BLOB | JSON-encoded face embedding |
| relationship_tier | TEXT | stranger/regular/favorite |
| relationship_score | REAL | 0.0–1.0 computed from encounters |
| interaction_count | INTEGER | Total encounters |
| positive_interactions | INTEGER | Count of positive encounters |
| greeting_stranger | TEXT | Greeting for strangers |
| greeting_regular | TEXT | Greeting for regular contacts |
| greeting_favorite | TEXT | Greeting for favorites |
| notes | TEXT | Custom observations |
| created_at | TIMESTAMP | When person was first recorded |
| last_seen | TIMESTAMP | Last encounter timestamp |
| last_tier_promotion | TIMESTAMP | Cooldown tracking |

### `encounters` Table
| Column | Type | Notes |
|--------|------|-------|
| encounter_id | INTEGER PRIMARY KEY | Auto-increment |
| person_id | INTEGER | Foreign key to persons |
| transcript | TEXT | Conversation text/summary |
| detected_mood | TEXT | Emotion detected during encounter |
| engagement_score | REAL | 0.0–1.0 |
| positive_interaction | BOOLEAN | Was interaction positive? |
| encounter_timestamp | TIMESTAMP | When encounter occurred |

### `backups` Table
| Column | Type | Notes |
|--------|------|-------|
| backup_id | INTEGER PRIMARY KEY | Auto-increment |
| backup_path | TEXT UNIQUE | Full path to backup file |
| backup_timestamp | TIMESTAMP | When backup was created |
| file_size_mb | REAL | Compressed size in MB |

## Configuration

Edit `config/social_memory.yaml`:

```yaml
database_path: "/home/seb/saltybot-data/social_memory.db"
backup_dir: "/home/seb/saltybot-data/backups"

publish_stats: true
stats_publish_interval: 60.0  # seconds

tier_promotion:
  regular_threshold: 5        # Encounters for regular tier
  favorite_threshold: 20      # Encounters for favorite tier
  positive_ratio_min: 0.8     # 80% positive required
  cooldown_hours: 1           # Minimum between promotions
```

## Running

### Launch the service node
```bash
ros2 launch saltybot_social_memory_node social_memory.launch.py
```

### Direct execution
```bash
ros2 run saltybot_social_memory_node social_memory
```

## Usage Examples

### Add a new person
```bash
ros2 service call /saltybot/social_memory/update saltybot_social_memory/PersonUpdate \
  "{name: 'Alice', relationship_tier: 'stranger', \
    custom_greetings: ['Hello there!', 'Nice to see you!', 'Great to see you again!']}"
```

### Record an encounter
```bash
ros2 service call /saltybot/social_memory/encounter saltybot_social_memory/EncounterRecord \
  "{person_id: 1, transcript: 'Alice: Hi! How are you?', \
    mood: 'happy', engagement_score: 0.85, positive_interaction: true}"
```

### Lookup a person
```bash
ros2 service call /saltybot/social_memory/lookup saltybot_social_memory/PersonLookup \
  "{query_type: 'name', query_value: 'Alice'}"
```

### Get database statistics
```bash
ros2 service call /saltybot/social_memory/stats saltybot_social_memory/DatabaseStats
```

### Monitor statistics stream
```bash
ros2 topic echo /saltybot/social_memory/stats_update
```

## Integration Points

1. **Emotion Engine** (`saltybot_emotion_engine`)
   - Queries person familiarity for warmth modifier
   - Records encounters to build relationship history

2. **Person Tracker** (`sl-perception`)
   - Provides person_id from face recognition
   - Supplies engagement_score and detected_mood

3. **Voice Recognition** (`sl-jetson`)
   - Provides transcript of conversations
   - Records as encounter transcript

4. **Greeting System**
   - Queries custom_greetings based on tier
   - Personalizes robot responses

## Tier Promotion Logic

```
When encounter recorded:
  1. Increment interaction_count
  2. Update positive_interactions if positive_interaction=true
  3. Compute positive_ratio = positive_interactions / interaction_count
  4. Check promotion eligibility:
     - current_tier == "stranger" && interaction_count >= 5 && positive_ratio >= 0.8
       → Promote to "regular"
     - current_tier == "regular" && interaction_count >= 20 && positive_ratio >= 0.8
       → Promote to "favorite"
  5. If promoted and cooldown_hours passed since last promotion:
     - Update relationship_tier
     - Set last_tier_promotion = now()
     - Return tier_changed_to in response
```

## Backup Strategy

- **Manual backups** via `backup_database()` method
- **Automatic tracking** in backups table with timestamp
- **Restore** from any backup: `restore_database(backup_path)`
- **Format**: gzip-compressed SQLite database (.db.gz)

## Thread Safety

- All database operations protected by `threading.Lock()`
- Safe for concurrent ROS2 service calls
- Sequential writes to ensure data integrity

## Performance Characteristics

- **Lookup**: O(1) indexed by person_id, O(n) by name pattern
- **Encounter recording**: O(1) insertion + O(1) stats update
- **Database size**: ~1KB per person + ~0.5KB per encounter

## Future Enhancements

1. Persistent memory integration with LLM (e.g., "Alice loves plants")
2. Group relationships (track person groups/families)
3. Preference learning (dietary restrictions, favorite topics)
4. Sentiment analysis over time
5. Web UI for person management
6. Integration with voice recognition confidence
7. Automated cleanup of old encounters (>1 year)
8. Graph-based relationship networks
