dac9f3dd02
Update Control API specification to use gRPC over Unix socket instead of JSON-RPC 2.0. gRPC provides better type safety, native streaming for events, and auto-generated clients for multi-language integration. architecture.md: - Add decision rationale table (JSON-RPC vs gRPC comparison) - Add full .proto definitions (~200 lines) for musicfs.v1 package - Define MusicFS service with 9 RPC methods: - Daemon: GetStatus, Shutdown - Cache: GetCacheStats, ClearCache, Prefetch (streaming) - Origins: ListOrigins, GetOriginHealth, RescanOrigin (streaming) - Search: Search, SearchStream - Events: SubscribeEvents (server-streaming) - Add grpcurl debugging examples requirements.md: - FR-17.1: Clarify Unix socket uses gRPC - FR-17.2: Upgrade from SHOULD to SHALL for gRPC requirement
650 lines
27 KiB
Markdown
650 lines
27 KiB
Markdown
# Music Library FUSE Filesystem - Requirements Specification
|
|
|
|
**Version**: 1.0
|
|
**Date**: 2026-05-12
|
|
**Status**: Draft
|
|
|
|
## 1. Introduction
|
|
|
|
### 1.1 Purpose
|
|
|
|
This document specifies the requirements for a FUSE-based virtual filesystem that presents a music library organized by metadata. The system overlays metadata onto audio files without modifying originals and operates as a read-only client against the origin storage.
|
|
|
|
### 1.2 Scope
|
|
|
|
The system provides:
|
|
- Virtual filesystem accessible via standard POSIX operations
|
|
- Metadata-based directory structure (artist/album/track)
|
|
- Local caching with delta synchronization
|
|
- Support for local and remote origin storage
|
|
|
|
### 1.3 Definitions
|
|
|
|
| Term | Definition |
|
|
|------|------------|
|
|
| **Origin** | The source storage containing original audio files (local FS, NFS, S3, etc.) |
|
|
| **Virtual path** | The metadata-derived path shown to users (e.g., `/Artist/Album/Track.flac`) |
|
|
| **Real path** | The actual path on origin storage |
|
|
| **Metadata overlay** | Serving synthesized file headers from cached metadata |
|
|
| **CDC** | Content-Defined Chunking - algorithm for stable file segmentation |
|
|
|
|
---
|
|
|
|
## 2. System Overview
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ User Applications │
|
|
│ (mpv, Rhythmbox, Plex, etc.) │
|
|
└─────────────────────────────┬───────────────────────────────────┘
|
|
│ POSIX (read-only)
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ FUSE Interface │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ Plugin Host │
|
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
│ │ Origin │ │ Metadata │ │ Format │ │
|
|
│ │ Plugins │ │ Plugins │ │ Plugins │ │
|
|
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ Core Services │
|
|
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
|
|
│ │ Virtual │ │ Event │ │ Search │ │ Control │ │
|
|
│ │ Path │ │ Bus │ │ Index │ │ API │ │
|
|
│ │ Resolver │ │ │ │ │ │ │ │
|
|
│ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ Storage Layer │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ Content-Addressable Chunk Store │ │
|
|
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
|
|
│ │ │ Metadata │ │ Content │ │ Tree │ │ │
|
|
│ │ │ Cache │ │ Chunks │ │ Cache │ │ │
|
|
│ │ │ (SQLite) │ │ (CAS) │ │ │ │ │
|
|
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ Origin Federation │
|
|
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
│ │ Local │ │ NFS │ │ S3 │ │ SFTP │ │
|
|
│ │ FS │ │ │ │ │ │ │ │
|
|
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
│ read-only
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ Origin Storage(s) │
|
|
│ (original audio files) │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Functional Requirements
|
|
|
|
### 3.1 Filesystem Operations
|
|
|
|
#### FR-1: Mount/Unmount
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-1.1 | The system SHALL mount as a FUSE filesystem at a user-specified mountpoint |
|
|
| FR-1.2 | The system SHALL return control to the caller within 500ms of mount initiation |
|
|
| FR-1.3 | The system SHALL unmount cleanly via `fusermount -u` |
|
|
| FR-1.4 | The system SHALL release all resources (file handles, connections) on unmount |
|
|
|
|
#### FR-2: Directory Operations
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-2.1 | The system SHALL present files organized by metadata path format |
|
|
| FR-2.2 | The system SHALL support configurable path templates (e.g., `$artist/$album/$track - $title.$format`) |
|
|
| FR-2.3 | The system SHALL return directory listings via `readdir()` |
|
|
| FR-2.4 | The system SHALL support nested directory traversal to arbitrary depth |
|
|
| FR-2.5 | The system SHALL handle directories with 100,000+ entries |
|
|
|
|
#### FR-3: File Operations (Read)
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-3.1 | The system SHALL support `open()` for reading |
|
|
| FR-3.2 | The system SHALL support `read()` with arbitrary offset and size |
|
|
| FR-3.3 | The system SHALL support `seek()` operations for random access |
|
|
| FR-3.4 | The system SHALL return file attributes via `stat()` / `fstat()` |
|
|
| FR-3.5 | The system SHALL support concurrent reads from multiple processes |
|
|
|
|
#### FR-4: Read-Only Constraint
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-4.1 | The system SHALL NOT modify original files on the origin storage |
|
|
| FR-4.2 | The system SHALL NOT push any changes to the origin server |
|
|
| FR-4.3 | The system SHALL return `EROFS` (Read-only filesystem) for write operations |
|
|
| FR-4.4 | The system SHALL return `EROFS` for `create()`, `mkdir()`, `unlink()`, `rmdir()` |
|
|
| FR-4.5 | The system SHALL return `EROFS` for `rename()`, `chmod()`, `chown()`, `truncate()` |
|
|
|
|
### 3.2 Metadata Handling
|
|
|
|
#### FR-5: Metadata Overlay
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-5.1 | The system SHALL extract metadata from audio files on first access |
|
|
| FR-5.2 | The system SHALL cache extracted metadata in a local database |
|
|
| FR-5.3 | The system SHALL serve file headers with metadata from cache |
|
|
| FR-5.4 | The system SHALL support FLAC Vorbis comments |
|
|
| FR-5.5 | The system SHALL support MP3 ID3v2 tags |
|
|
| FR-5.6 | The system SHOULD support additional formats (OGG, M4A, OPUS) |
|
|
|
|
#### FR-6: Metadata Fields
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-6.1 | The system SHALL extract and cache: title, artist, album, genre |
|
|
| FR-6.2 | The system SHALL extract and cache: year, track number, disc number |
|
|
| FR-6.3 | The system SHALL extract and cache: duration, bitrate, sample rate |
|
|
| FR-6.4 | The system SHOULD extract: composer, album artist, lyrics |
|
|
| FR-6.5 | The system SHALL handle missing metadata gracefully with defaults |
|
|
|
|
### 3.3 Caching
|
|
|
|
#### FR-7: Metadata Cache
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-7.1 | The system SHALL persist metadata cache across restarts |
|
|
| FR-7.2 | The system SHALL store metadata in SQLite database |
|
|
| FR-7.3 | The system SHALL index by both virtual path and real path |
|
|
| FR-7.4 | The system SHALL invalidate cache entries when origin file changes |
|
|
|
|
#### FR-8: Content Cache
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-8.1 | The system SHALL cache file content in fixed-size chunks |
|
|
| FR-8.2 | The system SHALL use content-defined chunking for cache efficiency |
|
|
| FR-8.3 | The system SHALL store chunk hashes for delta detection |
|
|
| FR-8.4 | The system SHALL evict chunks under memory/disk pressure |
|
|
|
|
#### FR-9: Directory Tree Cache
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-9.1 | The system SHALL cache directory listings locally |
|
|
| FR-9.2 | The system SHALL serve `readdir()` from cache without origin access |
|
|
| FR-9.3 | The system SHALL refresh tree cache based on configurable policy |
|
|
| FR-9.4 | The system SHALL support forced refresh via signal or special file |
|
|
|
|
### 3.4 Synchronization
|
|
|
|
#### FR-10: Change Detection
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-10.1 | The system SHALL detect changes to origin files |
|
|
| FR-10.2 | The system SHALL use inotify for local filesystem origins |
|
|
| FR-10.3 | The system SHALL use polling for remote origins without push support |
|
|
| FR-10.4 | The system SHALL compare mtime and size for change detection |
|
|
| FR-10.5 | The system SHALL support content-hash verification on demand |
|
|
|
|
#### FR-11: Delta Sync
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-11.1 | The system SHALL download only changed portions of files |
|
|
| FR-11.2 | The system SHALL use CDC to identify changed chunks |
|
|
| FR-11.3 | The system SHALL preserve unchanged chunks in cache |
|
|
| FR-11.4 | The system SHALL handle file additions and deletions |
|
|
|
|
### 3.5 Origin Support
|
|
|
|
#### FR-12: Origin Types
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-12.1 | The system SHALL support local filesystem as origin |
|
|
| FR-12.2 | The system SHOULD support NFS mounted filesystems |
|
|
| FR-12.3 | The system SHOULD support SMB/CIFS shares |
|
|
| FR-12.4 | The system SHOULD support S3-compatible object storage |
|
|
| FR-12.5 | The system SHOULD support SFTP servers |
|
|
| FR-12.6 | The system SHALL provide pluggable origin interface |
|
|
|
|
#### FR-13: Multiple Origins [P0]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-13.1 | The system SHALL support multiple simultaneous origins |
|
|
| FR-13.2 | The system SHALL present unified virtual tree across origins |
|
|
| FR-13.3 | The system SHALL support origin priority/preference ordering |
|
|
| FR-13.4 | The system SHALL handle duplicate files across origins |
|
|
| FR-13.5 | The system SHALL support per-origin configuration |
|
|
|
|
### 3.6 Search & Discovery
|
|
|
|
#### FR-14: Full-Text Search [P1]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-14.1 | The system SHALL index metadata for full-text search |
|
|
| FR-14.2 | The system SHALL expose search via virtual directory (`/.search/query/`) |
|
|
| FR-14.3 | The system SHALL support fuzzy matching |
|
|
| FR-14.4 | The system SHOULD support search by audio fingerprint |
|
|
|
|
#### FR-15: Smart Collections [P1]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-15.1 | The system SHALL support query-based virtual folders |
|
|
| FR-15.2 | The system SHALL support saved searches as directories |
|
|
| FR-15.3 | The system SHALL support dynamic playlists (recently played, most played) |
|
|
| FR-15.4 | The system SHOULD support user-defined metadata fields |
|
|
|
|
### 3.7 Album Art
|
|
|
|
#### FR-16: Cover Art Handling [P1]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-16.1 | The system SHALL extract embedded album art |
|
|
| FR-16.2 | The system SHALL expose art as virtual files (`/Artist/Album/cover.jpg`) |
|
|
| FR-16.3 | The system SHALL cache artwork separately from audio |
|
|
| FR-16.4 | The system SHALL support multiple art sizes (thumbnail, medium, full) |
|
|
| FR-16.5 | The system SHOULD fetch missing art from online sources |
|
|
|
|
### 3.8 Control & API
|
|
|
|
#### FR-17: Control Interface [P0]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-17.1 | The system SHALL expose control via Unix socket (gRPC) |
|
|
| FR-17.2 | The system SHALL use gRPC with Protocol Buffers for all control APIs |
|
|
| FR-17.3 | The system SHALL support cache management commands (clear, refresh, stats) |
|
|
| FR-17.4 | The system SHALL support runtime configuration changes |
|
|
| FR-17.5 | The system SHALL support graceful shutdown with drain |
|
|
|
|
#### FR-18: Event System [P0]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-18.1 | The system SHALL emit events for file access |
|
|
| FR-18.2 | The system SHALL support webhook notifications |
|
|
| FR-18.3 | The system SHOULD support event streaming (SSE/WebSocket) |
|
|
| FR-18.4 | The system SHALL log access patterns for analysis |
|
|
|
|
### 3.9 Caching Enhancements
|
|
|
|
#### FR-19: Intelligent Prefetching [P1]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-19.1 | The system SHALL learn access patterns |
|
|
| FR-19.2 | The system SHALL support playlist-aware prefetching |
|
|
| FR-19.3 | The system SHOULD support time-based prefetching |
|
|
| FR-19.4 | The system SHALL support manual prefetch hints (`/.prefetch/path/`) |
|
|
|
|
#### FR-20: Content-Addressable Storage [P0]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-20.1 | The system SHALL store chunks by content hash |
|
|
| FR-20.2 | The system SHALL detect identical files across library |
|
|
| FR-20.3 | The system SHALL report deduplication statistics |
|
|
| FR-20.4 | The system SHALL enable cache sharing via content addressing |
|
|
|
|
### 3.10 Integration
|
|
|
|
#### FR-21: Metadata Sources [P1]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-21.1 | The system SHOULD integrate with MusicBrainz |
|
|
| FR-21.2 | The system SHOULD integrate with Discogs |
|
|
| FR-21.3 | The system SHOULD integrate with Last.fm |
|
|
| FR-21.4 | The system SHOULD support AcoustID fingerprinting |
|
|
| FR-21.5 | The system SHALL support custom metadata plugins |
|
|
|
|
#### FR-22: Import & Migration [P1]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-22.1 | The system SHALL import from beets database |
|
|
| FR-22.2 | The system SHOULD import from iTunes/Apple Music library |
|
|
| FR-22.3 | The system SHALL export library metadata |
|
|
|
|
### 3.11 Extensibility
|
|
|
|
#### FR-23: Plugin System [P0]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-23.1 | The system SHALL support loadable plugins |
|
|
| FR-23.2 | The system SHALL define stable plugin API |
|
|
| FR-23.3 | The system SHALL support plugins for: origins, metadata extractors, formats |
|
|
| FR-23.4 | The system SHOULD support WASM plugins for sandboxed execution |
|
|
| FR-23.5 | The system SHALL provide plugin lifecycle management (load, unload, reload) |
|
|
|
|
#### FR-24: Format Extensibility [P1]
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-24.1 | The system SHALL support pluggable codec modules |
|
|
| FR-24.2 | The system SHOULD support audiobook formats (M4B, chapters) |
|
|
| FR-24.3 | The system SHALL allow format plugins to register file extensions |
|
|
|
|
### 3.12 High Availability [P3]
|
|
|
|
#### FR-25: Resilience
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| FR-25.1 | The system SHOULD support active-passive failover |
|
|
| FR-25.2 | The system SHOULD support read replicas |
|
|
| FR-25.3 | The system SHALL support zero-downtime upgrades |
|
|
| FR-25.4 | The system SHALL support cache backup/restore |
|
|
| FR-25.5 | The system SHALL validate cache integrity on startup |
|
|
|
|
---
|
|
|
|
## 4. Non-Functional Requirements
|
|
|
|
### 4.1 Performance
|
|
|
|
#### NFR-1: Latency
|
|
|
|
| ID | Requirement | Target | Maximum |
|
|
|----|-------------|--------|---------|
|
|
| NFR-1.1 | `stat()` on cached file | <1ms | 5ms |
|
|
| NFR-1.2 | `readdir()` on cached directory | <10ms | 50ms |
|
|
| NFR-1.3 | `open()` on cached file | <5ms | 20ms |
|
|
| NFR-1.4 | `read()` from cache | <1ms | 5ms |
|
|
| NFR-1.5 | `read()` cache miss (local origin) | <50ms | 200ms |
|
|
| NFR-1.6 | `read()` cache miss (remote origin) | <200ms | 1000ms |
|
|
| NFR-1.7 | Mount completion | <100ms | 500ms |
|
|
|
|
#### NFR-2: Throughput
|
|
|
|
| ID | Requirement | Target |
|
|
|----|-------------|--------|
|
|
| NFR-2.1 | Sequential read throughput (cached) | >500 MB/s |
|
|
| NFR-2.2 | Sequential read throughput (local origin) | >200 MB/s |
|
|
| NFR-2.3 | Metadata operations per second | >1000 ops/s |
|
|
| NFR-2.4 | Concurrent file handles | >1000 |
|
|
|
|
#### NFR-3: Scalability
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| NFR-3.1 | The system SHALL handle libraries with 1,000,000+ files |
|
|
| NFR-3.2 | The system SHALL handle directories with 100,000+ entries |
|
|
| NFR-3.3 | The system SHALL maintain O(1) mount time regardless of library size |
|
|
| NFR-3.4 | The system SHALL maintain O(log n) lookup time for paths |
|
|
| NFR-3.5 | The system SHOULD handle libraries with 10,000,000+ files [P3] |
|
|
| NFR-3.6 | The system SHOULD support 100+ concurrent clients [P3] |
|
|
| NFR-3.7 | The system SHOULD achieve <100μs cached stat for high-performance use [P3] |
|
|
|
|
### 4.2 Resource Usage
|
|
|
|
#### NFR-4: Memory
|
|
|
|
| ID | Requirement | Limit |
|
|
|----|-------------|-------|
|
|
| NFR-4.1 | Idle memory usage | <50 MB |
|
|
| NFR-4.2 | Active usage (1000 files accessed) | <200 MB |
|
|
| NFR-4.3 | Peak usage under load | <500 MB |
|
|
| NFR-4.4 | Per-file metadata overhead | <1 KB |
|
|
| NFR-4.5 | The system SHALL NOT load entire files into memory |
|
|
|
|
#### NFR-5: Disk
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| NFR-5.1 | Metadata cache size SHALL be configurable (default: 100 MB) |
|
|
| NFR-5.2 | Content cache size SHALL be configurable (default: 10 GB) |
|
|
| NFR-5.3 | The system SHALL evict cache entries under disk pressure |
|
|
| NFR-5.4 | The system SHALL function with cache disabled (passthrough mode) |
|
|
|
|
#### NFR-6: Network
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| NFR-6.1 | The system SHALL minimize network round-trips via batching |
|
|
| NFR-6.2 | The system SHALL use connection pooling for remote origins |
|
|
| NFR-6.3 | The system SHALL support bandwidth limiting (configurable) |
|
|
| NFR-6.4 | Delta sync SHALL achieve >90% bandwidth reduction vs full copy |
|
|
|
|
### 4.3 Reliability
|
|
|
|
#### NFR-7: Availability
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| NFR-7.1 | The system SHALL serve cached data when origin is unavailable |
|
|
| NFR-7.2 | The system SHALL gracefully degrade with network failures |
|
|
| NFR-7.3 | The system SHALL retry failed operations with exponential backoff |
|
|
| NFR-7.4 | The system SHALL not crash on malformed audio files |
|
|
|
|
#### NFR-8: Data Integrity
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| NFR-8.1 | The system SHALL verify chunk integrity via checksums |
|
|
| NFR-8.2 | The system SHALL use ACID transactions for cache database |
|
|
| NFR-8.3 | The system SHALL recover from interrupted synchronization |
|
|
| NFR-8.4 | The system SHALL detect and report cache corruption |
|
|
|
|
### 4.4 Usability
|
|
|
|
#### NFR-9: Configuration
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| NFR-9.1 | The system SHALL support configuration via file (TOML/YAML) |
|
|
| NFR-9.2 | The system SHALL support configuration via command-line arguments |
|
|
| NFR-9.3 | The system SHALL support configuration via environment variables |
|
|
| NFR-9.4 | The system SHALL provide sensible defaults for all options |
|
|
|
|
#### NFR-10: Observability
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| NFR-10.1 | The system SHALL log operations at configurable verbosity |
|
|
| NFR-10.2 | The system SHALL expose metrics (cache hit rate, latency, etc.) |
|
|
| NFR-10.3 | The system SHALL support health check endpoint/signal |
|
|
| NFR-10.4 | The system SHOULD support integration with Prometheus/StatsD |
|
|
|
|
### 4.5 Compatibility
|
|
|
|
#### NFR-11: Platform Support
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| NFR-11.1 | The system SHALL run on Linux (kernel 4.x+) |
|
|
| NFR-11.2 | The system SHOULD run on macOS (via macFUSE) |
|
|
| NFR-11.3 | The system SHALL require FUSE kernel module |
|
|
| NFR-11.4 | The system SHALL run without root privileges (user-space FUSE) |
|
|
|
|
#### NFR-12: Application Compatibility
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| NFR-12.1 | The system SHALL work with standard media players (mpv, VLC, etc.) |
|
|
| NFR-12.2 | The system SHALL work with media servers (Plex, Jellyfin) |
|
|
| NFR-12.3 | The system SHALL work with file managers (Nautilus, Dolphin) |
|
|
| NFR-12.4 | The system SHALL correctly report file sizes and timestamps |
|
|
|
|
### 4.6 Security
|
|
|
|
#### NFR-13: Access Control
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| NFR-13.1 | The system SHALL respect origin file permissions |
|
|
| NFR-13.2 | The system SHALL run as unprivileged user |
|
|
| NFR-13.3 | The system SHALL support credential storage for remote origins |
|
|
| NFR-13.4 | The system SHALL NOT expose credentials in logs or process list |
|
|
|
|
### 4.7 Maintainability
|
|
|
|
#### NFR-14: Code Quality
|
|
|
|
| ID | Requirement |
|
|
|----|-------------|
|
|
| NFR-14.1 | The system SHALL be implemented in a memory-safe language |
|
|
| NFR-14.2 | The system SHALL have no global interpreter lock (no Python/Ruby) |
|
|
| NFR-14.3 | The system SHALL use async I/O for concurrent operations |
|
|
| NFR-14.4 | The system SHALL have modular architecture with pluggable components |
|
|
|
|
---
|
|
|
|
## 5. Constraints
|
|
|
|
### 5.1 Technical Constraints
|
|
|
|
| ID | Constraint |
|
|
|----|------------|
|
|
| C-1 | Must use FUSE for filesystem interface |
|
|
| C-2 | Must not require kernel module development |
|
|
| C-3 | Must work with existing audio file formats (no transcoding) |
|
|
| C-4 | Cache database must be portable (no external database server) |
|
|
|
|
### 5.2 Operational Constraints
|
|
|
|
| ID | Constraint |
|
|
|----|------------|
|
|
| C-5 | Client is read-only; no writes propagate to origin |
|
|
| C-6 | Must function offline with cached data |
|
|
| C-7 | Must not corrupt origin files under any circumstances |
|
|
|
|
---
|
|
|
|
## 6. Assumptions
|
|
|
|
| ID | Assumption |
|
|
|----|------------|
|
|
| A-1 | Origin storage is accessible via supported protocol |
|
|
| A-2 | Audio files contain valid metadata headers |
|
|
| A-3 | Sufficient local disk space for caching is available |
|
|
| A-4 | FUSE kernel module is installed and accessible |
|
|
| A-5 | Network connectivity is intermittent but generally available |
|
|
|
|
---
|
|
|
|
## 7. Dependencies
|
|
|
|
| ID | Dependency | Purpose |
|
|
|----|------------|---------|
|
|
| D-1 | FUSE library (fuser/libfuse) | Filesystem interface |
|
|
| D-2 | SQLite | Metadata and tree cache |
|
|
| D-3 | Audio parsing library (symphonia) | Metadata extraction |
|
|
| D-4 | Async runtime (tokio) | Concurrent I/O |
|
|
| D-5 | CDC library (fastcdc) | Content chunking |
|
|
| D-6 | Full-text search (tantivy) | Search index [P1] |
|
|
| D-7 | Image processing (image) | Album art thumbnails [P1] |
|
|
| D-8 | HTTP client (reqwest) | Remote origins, metadata APIs |
|
|
| D-9 | WASM runtime (wasmtime) | Plugin sandboxing [P0] |
|
|
| D-10 | Hash library (xxhash/blake3) | Content addressing [P0] |
|
|
|
|
---
|
|
|
|
## 8. Acceptance Criteria
|
|
|
|
### 8.1 Functional Acceptance
|
|
|
|
| ID | Criterion |
|
|
|----|-----------|
|
|
| AC-1 | Mount filesystem and browse directories via `ls` |
|
|
| AC-2 | Play audio file through mounted filesystem with media player |
|
|
| AC-3 | Seek within audio file without full download |
|
|
| AC-4 | Directory listing completes without network access (when cached) |
|
|
| AC-5 | Confirm write operations return EROFS |
|
|
| AC-6 | Detect and sync changes from origin within configured interval |
|
|
|
|
### 8.2 Performance Acceptance
|
|
|
|
| ID | Criterion |
|
|
|----|-----------|
|
|
| AC-7 | Mount completes in <500ms for library of any size |
|
|
| AC-8 | Cached stat() completes in <5ms (p99) |
|
|
| AC-9 | Memory stays under 500MB with 10,000 files accessed |
|
|
| AC-10 | Tag-only change syncs <10KB of data |
|
|
|
|
### 8.3 Reliability Acceptance
|
|
|
|
| ID | Criterion |
|
|
|----|-----------|
|
|
| AC-11 | Filesystem remains accessible when origin is offline |
|
|
| AC-12 | No data corruption after unclean unmount |
|
|
| AC-13 | Recovers automatically when origin comes back online |
|
|
|
|
### 8.4 Multi-Origin Acceptance [P0]
|
|
|
|
| ID | Criterion |
|
|
|----|-----------|
|
|
| AC-14 | Configure and mount multiple origins simultaneously |
|
|
| AC-15 | Browse unified tree showing content from all origins |
|
|
| AC-16 | Access same file from preferred origin when duplicated |
|
|
|
|
### 8.5 Search & Discovery Acceptance [P1]
|
|
|
|
| ID | Criterion |
|
|
|----|-----------|
|
|
| AC-17 | Search for tracks by partial artist/album/title match |
|
|
| AC-18 | Browse smart collection (e.g., "Jazz from 1960s") |
|
|
| AC-19 | View album art via virtual cover.jpg file |
|
|
|
|
### 8.6 Plugin Acceptance [P0]
|
|
|
|
| ID | Criterion |
|
|
|----|-----------|
|
|
| AC-20 | Load custom origin plugin at runtime |
|
|
| AC-21 | Control daemon via Unix socket (cache stats, refresh) |
|
|
| AC-22 | Receive webhook on file access event |
|
|
|
|
### 8.7 Deduplication Acceptance [P0]
|
|
|
|
| ID | Criterion |
|
|
|----|-----------|
|
|
| AC-23 | Identical chunks stored once regardless of file count |
|
|
| AC-24 | Deduplication stats visible via control API |
|
|
|
|
---
|
|
|
|
## 9. Appendix
|
|
|
|
### 9.1 Comparison with beetfs
|
|
|
|
| Requirement Area | beetfs | This Specification |
|
|
|------------------|--------|-------------------|
|
|
| Mount time | O(N), 5-120s | O(1), <500ms (NFR-1.7) |
|
|
| Memory per file | Full file size | <1KB (NFR-4.4) |
|
|
| Write to origin | Yes (DB updates) | No (FR-4.1, FR-4.2) |
|
|
| Delta sync | None | Required (FR-11) |
|
|
| Remote origins | None | Required (FR-12) |
|
|
| Offline access | No | Required (NFR-7.1) |
|
|
| Cache persistence | No | Required (FR-7.1) |
|
|
|
|
### 9.2 Path Template Variables
|
|
|
|
| Variable | Description | Example |
|
|
|----------|-------------|---------|
|
|
| `$artist` | Track artist | "Metallica" |
|
|
| `$album` | Album name | "72 Seasons" |
|
|
| `$title` | Track title | "Lux Æterna" |
|
|
| `$track` | Track number (zero-padded) | "03" |
|
|
| `$disc` | Disc number | "1" |
|
|
| `$year` | Release year | "2023" |
|
|
| `$genre` | Genre | "Metal" |
|
|
| `$format` | File extension | "flac" |
|
|
| `$format_upper` | File extension (uppercase) | "FLAC" |
|
|
|
|
### 9.3 Error Codes
|
|
|
|
| Operation | Error | Code |
|
|
|-----------|-------|------|
|
|
| Any write operation | Read-only filesystem | EROFS (30) |
|
|
| File not found | No such file | ENOENT (2) |
|
|
| Origin unavailable | I/O error | EIO (5) |
|
|
| Permission denied | Access denied | EACCES (13) |
|