# Runtime Content-Addressed Store

## Description

This proposal outlines the addition of a content-addressed storage system to the Theater runtime. The store will provide a persistent, deduplicated, and verifiable storage mechanism for data used throughout the system.

- **What is being changed**: Adding a content-addressed store that will store data by its hash and provide a labeling system to reference stored data.
  
- **Why this change is necessary**: 
  1. The runtime needs a way to persistently store content that can be verified and deduplicated
  2. Content-addressing ensures data integrity by design
  3. A labeling system allows for flexible organization and retrieval of stored data
  
- **Expected benefits**:
  1. Data deduplication (same content is stored only once)
  2. Data integrity (content hashing verifies data hasn't been tampered with)
  3. Consistent addressing scheme for any type of content
  4. Foundation for future runtime features like event archives and registries
  
- **Potential risks**:
  1. Performance overhead from hashing large data
  2. Storage management complexity
  3. Increased filesystem usage
  
- **Alternatives considered**:
  1. Using a database instead of the filesystem
  2. Using a third-party content-addressed storage system
  3. Implementing different storage solutions for different content types

## Technical Specification

### Core Components

1. **ContentStore**: The main interface for store operations
2. **ContentRef**: A reference to stored content (containing the hash)
3. **LabelMap**: Mapping between labels and content hashes

### Storage Structure

```
theater/
  └── store/
      ├── data/
      │   ├── {hash1}
      │   ├── {hash2}
      │   └── ...
      └── labels/
          ├── {label1}
          ├── {label2}
          └── ...
```

### Hash Calculation

- SHA1 hash of the content will be used for addressing
- Hashes will be encoded as hex strings for filesystem paths

### API Design

```rust
/// Content store for Theater runtime
pub struct ContentStore {
    base_path: PathBuf,
}

impl ContentStore {
    /// Create a new store with the given base path
    pub fn new(base_path: PathBuf) -> Self;
    
    /// Initialize the store (create necessary directories)
    pub async fn init(&self) -> Result<()>;
    
    /// Store content and return its ContentRef
    pub async fn store(&self, content: Vec<u8>) -> Result<ContentRef>;
    
    /// Retrieve content by its reference
    pub async fn get(&self, content_ref: &ContentRef) -> Result<Vec<u8>>;
    
    /// Check if content exists
    pub async fn exists(&self, content_ref: &ContentRef) -> bool;
    
    /// Attach a label to content
    pub async fn label(&self, label: &str, content_ref: &ContentRef) -> Result<()>;
    
    /// Get content references by label
    pub async fn get_by_label(&self, label: &str) -> Result<Vec<ContentRef>>;
    
    /// Remove a label
    pub async fn remove_label(&self, label: &str) -> Result<()>;
    
    /// Remove a specific content reference from a label
    pub async fn remove_from_label(&self, label: &str, content_ref: &ContentRef) -> Result<()>;
    
    /// List all labels
    pub async fn list_labels(&self) -> Result<Vec<String>>;
    
    /// List all content references
    pub async fn list_all_content(&self) -> Result<Vec<ContentRef>>;
    
    /// Calculate total size of all content in the store
    pub async fn calculate_total_size(&self) -> Result<u64>;
}

/// Reference to content in the store
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ContentRef {
    hash: String,
}

impl ContentRef {
    /// Create from existing hash
    pub fn new(hash: String) -> Self;
    
    /// Get the hash as a string
    pub fn hash(&self) -> &str;
    
    /// Convert to a path for storage
    fn to_path(&self, base_path: &Path) -> PathBuf;
    
    /// Create a ContentRef by hashing content
    pub fn from_content(content: &[u8]) -> Self;
}
```

### Integration with Theater Runtime

The content store will be instantiated by the Theater runtime during initialization:

```rust
// In theater_runtime.rs

pub struct TheaterRuntime {
    // Existing fields...
    content_store: ContentStore,
}

impl TheaterRuntime {
    pub async fn new(config: Config) -> Result<Self> {
        // Create content store
        let store_path = config.store_path.unwrap_or_else(|| PathBuf::from("theater/store"));
        let content_store = ContentStore::new(store_path);
        content_store.init().await?;
        
        // Rest of initialization...
        
        Ok(Self {
            // Other fields...
            content_store,
        })
    }
}
```

For now, the store will be focused on the core functionality without implementing any specific integrations with actors or the event system. These integrations will be proposed separately once the base store implementation is complete and tested.

## Implementation Plan

1. Create `ContentRef` struct
2. Implement core `ContentStore` functionality
   - Storage and retrieval
   - Content existence check
   - Label operations
3. Add utility methods
   - Listing labels
   - Listing all content
   - Size calculation
4. Add tests for all functionality
5. Integrate with Theater runtime

## Future Enhancements

After the core implementation is complete, we can consider:

1. Garbage collection for unreferenced content
2. Content compression for large data
3. Streaming API for large content
4. Content metadata (creation time, mime type, etc.)
5. Integration with the event system for event archives
6. Integration with the manifest system for a component registry
7. Integration with the actor system for configuration storage
