Files
c-relay/.roo/architect/AGENTS.md
2025-09-13 08:49:09 -04:00

298 lines
12 KiB
Markdown

# AGENTS.md - AI Agent Integration Guide for Architect Mode
**Project-Specific Information for AI Agents Working with C-Relay in Architect Mode**
## Critical Architecture Understanding
### System Architecture Overview
C-Relay implements a **unique event-based configuration architecture** that fundamentally differs from traditional Nostr relays:
```
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ WebSocket │ │ Configuration │ │ Database │
│ + HTTP │◄──►│ Event System │◄──►│ (SQLite) │
│ (Port 8888) │ │ (Kind 33334) │ │ Schema v4 │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ nostr_core_lib │ │ Admin Key │ │ Event Storage │
│ (Crypto/Sigs) │ │ Management │ │ + Subscriptions │
└─────────────────┘ └──────────────────┘ └─────────────────┘
```
### Core Architectural Principles
#### 1. Event-Driven Configuration
**Design Philosophy**: Configuration as cryptographically signed events rather than files
- **Benefits**: Auditability, remote management, tamper-evidence
- **Trade-offs**: Complexity in configuration changes, admin key management burden
- **Implementation**: Kind 33334 events stored in same database as relay events
#### 2. Identity-Based Database Naming
**Design Philosophy**: Database file named by relay's generated public key
- **Benefits**: Prevents database conflicts, enables multi-relay deployments
- **Trade-offs**: Cannot predict database filename, complicates backup strategies
- **Implementation**: `<relay_pubkey>.db` created in build/ directory
#### 3. Single-Binary Deployment
**Design Philosophy**: All functionality embedded in one executable
- **Benefits**: Simple deployment, no external dependencies to manage
- **Trade-offs**: Larger binary size, harder to modularize
- **Implementation**: SQL schema embedded as header file, nostr_core_lib as submodule
#### 4. Dual-Protocol Support
**Design Philosophy**: WebSocket (Nostr) and HTTP (NIP-11) on same port
- **Benefits**: Simplified port management, reduced infrastructure complexity
- **Trade-offs**: Protocol detection overhead, libwebsockets dependency
- **Implementation**: Request routing based on HTTP headers and upgrade requests
## Architectural Decision Analysis
### Configuration System Design
**Traditional Approach vs C-Relay:**
```
Traditional: C-Relay:
config.json → kind 33334 events
ENV variables → cryptographically signed tags
File watching → database polling/restart
```
**Implications for Extensions:**
- Configuration changes require event signing capabilities
- No hot-reloading without architectural changes
- Admin key loss = complete database reset required
### Database Architecture Decisions
**Schema Design Philosophy:**
- **Event Tags as JSON**: Separate table with JSON column instead of normalized relations
- **Application-Level Filtering**: NIP-40 expiration handled in C, not SQL
- **Embedded Schema**: Version 4 schema compiled into binary
**Scaling Considerations:**
- SQLite suitable for small-to-medium relays (< 10k concurrent connections)
- Single-writer limitation of SQLite affects write-heavy workloads
- JSON tag storage optimizes for read performance over write normalization
### Memory Management Architecture
**Thread Safety Model:**
- Global subscription manager with mutex protection
- Per-client subscription limits enforced in memory
- WebSocket connection state managed by libwebsockets
**Resource Management:**
- JSON objects use reference counting (jansson library)
- String duplication pattern for configuration values
- Automatic cleanup on client disconnect
## Architectural Extension Points
### Adding New Configuration Options
**Required Changes:**
1. Update [`default_config_event.h`](src/default_config_event.h) template
2. Add parsing logic in [`config.c`](src/config.c) `load_config_from_database()`
3. Add global config struct field in [`config.h`](src/config.h)
4. Update documentation in [`docs/configuration_guide.md`](docs/configuration_guide.md)
### Adding New NIP Support
**Integration Pattern:**
1. Event validation in [`request_validator.c`](src/request_validator.c)
2. Protocol handling in [`main.c`](src/main.c) WebSocket callback
3. Database storage considerations in schema
4. Add test in `tests/` directory
### Scaling Architecture
**Current Limitations:**
- Single process, no horizontal scaling
- SQLite single-writer bottleneck
- Memory-based subscription management
**Potential Extensions:**
- Redis for subscription state sharing
- PostgreSQL for better concurrent write performance
- Load balancer for read scaling with multiple instances
## Deployment Architecture Patterns
### Development Deployment
```
Developer Machine:
├── ./make_and_restart_relay.sh
├── build/c_relay_x86
├── build/<relay_pubkey>.db
└── relay.log
```
### Production SystemD Deployment
```
/opt/c-relay/:
├── c_relay_x86
├── <relay_pubkey>.db
├── systemd service (c-relay.service)
└── c-relay user isolation
```
### Container Deployment Architecture
```
Container:
├── Multi-stage build (deps + binary)
├── Volume mount for database persistence
├── Health checks via NIP-11 endpoint
└── Signal handling for graceful shutdown
```
### Reverse Proxy Architecture
```
Internet → Nginx/HAProxy → C-Relay
├── WebSocket upgrade handling
├── SSL termination
└── Rate limiting
```
## Security Architecture Considerations
### Key Management Design
**Admin Key Security Model:**
- Generated once, displayed once, never stored
- Required for all configuration changes
- Loss requires complete database reset
**Relay Identity Model:**
- Separate keypair for relay identity
- Public key used for database naming
- Private key never exposed to clients
### Event Validation Pipeline
```
WebSocket Input → JSON Parse → Schema Validate → Signature Verify → Store
↓ ↓ ↓
reject reject reject success
```
### Attack Surface Analysis
**Network Attack Vectors:**
- WebSocket connection flooding (mitigated by libwebsockets limits)
- JSON parsing attacks (handled by jansson library bounds checking)
- SQLite injection (prevented by prepared statements)
**Configuration Attack Vectors:**
- Admin key compromise (complete relay control)
- Event signature forgery (prevented by nostr_core_lib validation)
- Replay attacks (event timestamp validation required)
## Non-Obvious Architectural Considerations
### Database Evolution Strategy
**Current Limitations:**
- Schema changes require database recreation
- No migration system for configuration events
- Version 4 schema embedded in binary
**Future Architecture Needs:**
- Schema versioning and migration system
- Backward compatibility for configuration events
- Database backup/restore procedures
### Configuration Event Lifecycle
**Event Flow:**
```
Admin Signs Event → WebSocket Submit → Validate → Store → Restart Required
↓ ↓ ↓
Signature Check Database Config Reload
```
**Architectural Implications:**
- No hot configuration reloading
- Configuration changes require planned downtime
- Event ordering matters for multiple simultaneous changes
### Cross-Architecture Deployment
**Build System Architecture:**
- Auto-detection of host architecture
- Cross-compilation support for ARM64
- Architecture-specific binary outputs
**Deployment Implications:**
- Binary must match target architecture
- Dependencies must be available for target architecture
- Debug tooling architecture-specific
### Performance Architecture Characteristics
**Bottlenecks:**
1. **SQLite Write Performance**: Single writer limitation
2. **JSON Parsing**: Per-event parsing overhead
3. **Signature Validation**: Cryptographic operations per event
4. **Memory Management**: JSON object lifecycle management
**Optimization Points:**
- Prepared statement reuse
- Connection pooling for concurrent reads
- Event batching for bulk operations
- Subscription indexing strategies
### Integration Architecture Patterns
**Monitoring Integration:**
- NIP-11 endpoint for health checks
- Log file monitoring for operational metrics
- Database query monitoring for performance
- Process monitoring for resource usage
**Backup Architecture:**
- Database file backup (SQLite file copy)
- Configuration event export/import
- Admin key secure storage (external to relay)
### Future Extension Architectures
**Multi-Relay Coordination:**
- Database sharding by event kind
- Cross-relay event synchronization
- Distributed configuration management
**Plugin Architecture Possibilities:**
- Event processing pipeline hooks
- Custom validation plugins
- External authentication providers
**Scaling Architecture Options:**
- Read replicas with PostgreSQL migration
- Event stream processing with message queues
- Microservice decomposition (auth, storage, validation)
## Architectural Anti-Patterns to Avoid
1. **Configuration File Addition**: Breaks event-based config paradigm
2. **Direct Database Modification**: Bypasses signature validation
3. **Hard-Coded Ports**: Conflicts with auto-fallback system
4. **Schema Modifications**: Requires database recreation
5. **Admin Key Storage**: Violates security model
6. **Blocking Operations**: Interferes with WebSocket event loop
7. **Memory Leaks**: JSON objects must be properly reference counted
8. **Thread Unsafe Operations**: Global state requires proper synchronization
## Architecture Decision Records (Implicit)
### Decision: Event-Based Configuration
**Context**: Traditional config files vs. cryptographic auditability
**Decision**: Store configuration as signed Nostr events
**Consequences**: Complex configuration changes, enhanced security, remote management capability
### Decision: SQLite Database
**Context**: Database choice for relay storage
**Decision**: Embedded SQLite with JSON tag storage
**Consequences**: Simple deployment, single-writer limitation, application-level filtering
### Decision: Single Binary Deployment
**Context**: Dependency management vs. deployment simplicity
**Decision**: Embed all dependencies and schema in binary
**Consequences**: Larger binary, simple deployment, version coupling
### Decision: Dual Protocol Support
**Context**: WebSocket for Nostr, HTTP for NIP-11
**Decision**: Same port serves both protocols
**Consequences**: Simplified deployment, protocol detection overhead, libwebsockets dependency
These architectural decisions form the foundation of C-Relay's unique approach to Nostr relay implementation and should be carefully considered when planning extensions or modifications.
**
[Response interrupted by a tool use result. Only one tool may be used at a time and should be placed at the end of the message.]