# Phase 2A: Canonical Edition Scoring - Detailed Design
> **Tasks**: T-400 to T-402
> **Branch**: `experimental/brainz`
> **Dependencies**: Phase 1 (MusicBrainz/Chromaprint integration)
---
## Overview
Canonical scoring enables slskdn to identify the "best" version of each recording across multiple variants observed in the network. This allows smart download decisions: prefer canonical masters, avoid transcodes, and surface upgrade opportunities in the Library Health UI.
---
## 1. AudioVariant Data Model (T-400)
### 1.1. Core Data Structure
```csharp
namespace slskd.Audio
{
///
/// Represents a specific encoded variant of a recording.
///
public class AudioVariant
{
// Identity
public string VariantId { get; set; } // Local unique ID
public string MusicBrainzRecordingId { get; set; }
public string FlacKey { get; set; } // SHA256 of FLAC audio MD5
// Technical Properties
public string Codec { get; set; } // "FLAC", "MP3", "AAC", "ALAC", "Opus", "Vorbis"
public string Container { get; set; } // "FLAC", "MP3", "M4A", "OGG", "MKA"
public int SampleRateHz { get; set; } // 44100, 48000, 96000, 192000
public int? BitDepth { get; set; } // 16, 24 (null for lossy)
public int Channels { get; set; } // 1 (mono), 2 (stereo), 6 (5.1)
public int DurationMs { get; set; }
public int BitrateKbps { get; set; } // Average bitrate
public long FileSizeBytes { get; set; }
// Content Integrity
public string FileSha256 { get; set; }
public string AudioFingerprint { get; set; } // Chromaprint
// Quality Assessment
public double QualityScore { get; set; } // 0.0 to 1.0
public bool TranscodeSuspect { get; set; }
public string TranscodeReason { get; set; } // Human-readable
// Audio Analysis (optional, computed on-demand)
public double? DynamicRangeDR { get; set; } // DR meter
public double? LoudnessLUFS { get; set; } // EBU R128
public bool? HasClipping { get; set; }
public string EncoderSignature { get; set; } // e.g., "LAME 3.100"
// Provenance
public DateTimeOffset FirstSeenAt { get; set; }
public DateTimeOffset LastSeenAt { get; set; }
public int SeenCount { get; set; } // How many times observed
}
}
```
### 1.2. Codec Profile Derivation
```csharp
namespace slskd.Audio
{
///
/// Standardized codec profile for grouping variants.
///
public class CodecProfile
{
public string Codec { get; set; }
public bool IsLossless { get; set; }
public int SampleRateHz { get; set; }
public int? BitDepth { get; set; }
public int Channels { get; set; }
///
/// Generate a canonical string key for this profile.
///
public string ToKey()
{
if (IsLossless && BitDepth.HasValue)
{
return $"{Codec}-{BitDepth}bit-{SampleRateHz}Hz-{Channels}ch";
}
return $"{Codec}-lossy-{SampleRateHz}Hz-{Channels}ch";
}
///
/// Parse audio file and derive codec profile.
///
public static CodecProfile FromFile(string filePath)
{
using var file = TagLib.File.Create(filePath);
var props = file.Properties;
return new CodecProfile
{
Codec = GetCodecName(props),
IsLossless = IsLosslessCodec(props),
SampleRateHz = props.AudioSampleRate,
BitDepth = GetBitDepth(props),
Channels = props.AudioChannels
};
}
}
}
```
### 1.3. Database Schema Extension
```sql
-- Extend HashDb table with variant metadata
ALTER TABLE HashDb ADD COLUMN variant_id TEXT;
ALTER TABLE HashDb ADD COLUMN codec TEXT;
ALTER TABLE HashDb ADD COLUMN container TEXT;
ALTER TABLE HashDb ADD COLUMN sample_rate_hz INTEGER;
ALTER TABLE HashDb ADD COLUMN bit_depth INTEGER;
ALTER TABLE HashDb ADD COLUMN channels INTEGER;
ALTER TABLE HashDb ADD COLUMN duration_ms INTEGER;
ALTER TABLE HashDb ADD COLUMN bitrate_kbps INTEGER;
ALTER TABLE HashDb ADD COLUMN quality_score REAL DEFAULT 0.0;
ALTER TABLE HashDb ADD COLUMN transcode_suspect BOOLEAN DEFAULT FALSE;
ALTER TABLE HashDb ADD COLUMN transcode_reason TEXT;
ALTER TABLE HashDb ADD COLUMN dynamic_range_dr REAL;
ALTER TABLE HashDb ADD COLUMN loudness_lufs REAL;
ALTER TABLE HashDb ADD COLUMN has_clipping BOOLEAN;
ALTER TABLE HashDb ADD COLUMN encoder_signature TEXT;
ALTER TABLE HashDb ADD COLUMN seen_count INTEGER DEFAULT 1;
-- Index for variant lookups
CREATE INDEX idx_hashdb_variant ON HashDb(variant_id);
CREATE INDEX idx_hashdb_recording_codec ON HashDb(musicbrainz_id, codec, sample_rate_hz);
```
---
## 2. Quality Scoring Algorithm (T-400)
### 2.1. Scoring Components
Quality score is computed as a weighted sum of multiple factors:
```csharp
public class QualityScorer
{
public double ComputeQualityScore(AudioVariant variant)
{
double score = 0.0;
// Component 1: Codec fidelity (0.4 weight)
score += 0.4 * ComputeCodecScore(variant);
// Component 2: Sample rate plausibility (0.2 weight)
score += 0.2 * ComputeSampleRateScore(variant);
// Component 3: Bitrate adequacy (0.2 weight)
score += 0.2 * ComputeBitrateScore(variant);
// Component 4: Audio analysis (0.2 weight, if available)
score += 0.2 * ComputeAnalysisScore(variant);
return Math.Clamp(score, 0.0, 1.0);
}
private double ComputeCodecScore(AudioVariant v)
{
// Lossless codecs get full score
if (v.Codec == "FLAC" && v.BitDepth >= 16) return 1.0;
if (v.Codec == "ALAC" && v.BitDepth >= 16) return 0.98;
if (v.Codec == "WAV" && v.BitDepth >= 16) return 0.95;
// High-quality lossy
if (v.Codec == "MP3" && v.BitrateKbps >= 320) return 0.75;
if (v.Codec == "AAC" && v.BitrateKbps >= 256) return 0.73;
if (v.Codec == "Opus" && v.BitrateKbps >= 160) return 0.70;
if (v.Codec == "Vorbis" && v.BitrateKbps >= 256) return 0.68;
// Low-quality lossy
if (v.BitrateKbps >= 192) return 0.5;
if (v.BitrateKbps >= 128) return 0.3;
return 0.1;
}
private double ComputeSampleRateScore(AudioVariant v)
{
// Standard rates get full score
if (v.SampleRateHz == 44100 || v.SampleRateHz == 48000) return 1.0;
// High-res audio
if (v.SampleRateHz == 88200 || v.SampleRateHz == 96000) return 0.95;
if (v.SampleRateHz == 176400 || v.SampleRateHz == 192000) return 0.90;
// Unusual/suspicious rates (possible upsampling)
if (v.SampleRateHz == 22050 || v.SampleRateHz == 11025) return 0.4;
return 0.5; // Unknown rate
}
private double ComputeBitrateScore(AudioVariant v)
{
// For lossless, check if bitrate is reasonable for format
if (v.Codec == "FLAC")
{
int expectedMin = EstimateFLACBitrate(v.SampleRateHz, v.BitDepth ?? 16, v.Channels);
if (v.BitrateKbps < expectedMin * 0.5)
{
// Suspiciously low bitrate for lossless
return 0.3;
}
return 1.0;
}
// For lossy, higher bitrate is better (up to a point)
if (v.BitrateKbps >= 320) return 1.0;
if (v.BitrateKbps >= 256) return 0.9;
if (v.BitrateKbps >= 192) return 0.7;
if (v.BitrateKbps >= 128) return 0.5;
return 0.2;
}
private double ComputeAnalysisScore(AudioVariant v)
{
if (!v.DynamicRangeDR.HasValue) return 0.5; // No data, neutral
double score = 0.5;
// Good dynamic range
if (v.DynamicRangeDR >= 10) score += 0.3;
else if (v.DynamicRangeDR >= 7) score += 0.1;
else score -= 0.2; // Poor DR suggests over-compression or transcode
// Clipping penalty
if (v.HasClipping == true) score -= 0.3;
return Math.Clamp(score, 0.0, 1.0);
}
private int EstimateFLACBitrate(int sampleRate, int bitDepth, int channels)
{
// FLAC typically compresses to 50-60% of raw PCM
int rawBitrate = (sampleRate * bitDepth * channels) / 1000;
return (int)(rawBitrate * 0.55);
}
}
```
### 2.2. Transcode Detection Heuristics
```csharp
public class TranscodeDetector
{
public (bool isSuspect, string reason) DetectTranscode(AudioVariant variant)
{
// Rule 1: FLAC with impossibly low bitrate
if (variant.Codec == "FLAC")
{
int minExpected = EstimateMinFLACBitrate(variant);
if (variant.BitrateKbps < minExpected)
{
return (true, $"FLAC bitrate {variant.BitrateKbps}kbps too low for {variant.SampleRateHz}Hz/{variant.BitDepth}bit (expected ≥{minExpected}kbps)");
}
}
// Rule 2: Lossless with poor dynamic range
if (IsLosslessCodec(variant.Codec) && variant.DynamicRangeDR.HasValue)
{
if (variant.DynamicRangeDR < 5)
{
return (true, $"Lossless file with DR={variant.DynamicRangeDR:F1} suggests lossy source");
}
}
// Rule 3: Upsampled audio (48kHz or 96kHz from 44.1kHz source)
if (variant.SampleRateHz == 48000 || variant.SampleRateHz == 96000)
{
// Check encoder signature for clues
if (variant.EncoderSignature != null &&
variant.EncoderSignature.Contains("LAME")) // MP3 encoder in FLAC
{
return (true, "Lossy encoder signature in lossless file");
}
}
// Rule 4: Spectral analysis (if available)
if (variant.BitrateKbps > 0)
{
double effectiveBandwidth = EstimateSpectralBandwidth(variant);
double expectedBandwidth = variant.SampleRateHz / 2.0;
if (effectiveBandwidth < expectedBandwidth * 0.6)
{
return (true, $"Spectral bandwidth {effectiveBandwidth/1000:F1}kHz suggests {EstimateOriginalLossyBitrate(effectiveBandwidth)}kbps lossy source");
}
}
return (false, null);
}
private double EstimateSpectralBandwidth(AudioVariant variant)
{
// Placeholder: would require FFT analysis
// For now, estimate from bitrate for lossy codecs
if (variant.Codec == "MP3")
{
if (variant.BitrateKbps >= 320) return 20000;
if (variant.BitrateKbps >= 192) return 18000;
if (variant.BitrateKbps >= 128) return 16000;
return 14000;
}
return variant.SampleRateHz / 2.0; // Nyquist frequency
}
}
```
---
## 3. Canonical Stats Aggregation (T-401)
### 3.1. Data Structure
```csharp
namespace slskd.Audio
{
///
/// Aggregated statistics for a (Recording ID, Codec Profile) pair.
///
public class CanonicalStats
{
public string MusicBrainzRecordingId { get; set; }
public string CodecProfileKey { get; set; }
// Aggregated counts
public int VariantCount { get; set; }
public int TotalSeenCount { get; set; } // Sum of all variant seen_counts
// Quality metrics
public double AvgQualityScore { get; set; }
public double MaxQualityScore { get; set; }
public double PercentTranscodeSuspect { get; set; }
// Distributions
public Dictionary CodecDistribution { get; set; }
public Dictionary BitrateDistribution { get; set; }
public Dictionary SampleRateDistribution { get; set; }
// Canonical candidate
public string BestVariantId { get; set; } // Variant with highest quality score
public double CanonicalityScore { get; set; } // 0.0 to 1.0
public DateTimeOffset LastUpdated { get; set; }
}
}
```
### 3.2. Database Schema
```sql
CREATE TABLE CanonicalStats (
id TEXT PRIMARY KEY,
musicbrainz_recording_id TEXT NOT NULL,
codec_profile_key TEXT NOT NULL,
variant_count INTEGER DEFAULT 0,
total_seen_count INTEGER DEFAULT 0,
avg_quality_score REAL DEFAULT 0.0,
max_quality_score REAL DEFAULT 0.0,
percent_transcode_suspect REAL DEFAULT 0.0,
codec_distribution TEXT, -- JSON
bitrate_distribution TEXT, -- JSON
sample_rate_distribution TEXT, -- JSON
best_variant_id TEXT,
canonicality_score REAL DEFAULT 0.0,
last_updated INTEGER NOT NULL
);
CREATE INDEX idx_canonical_recording ON CanonicalStats(musicbrainz_recording_id);
CREATE INDEX idx_canonical_profile ON CanonicalStats(codec_profile_key);
CREATE INDEX idx_canonical_score ON CanonicalStats(canonicality_score DESC);
```
### 3.3. Aggregation Service
```csharp
namespace slskd.Audio
{
public interface ICanonicalStatsService
{
///
/// Recompute canonical stats for a recording/codec combination.
///
Task AggregateStatsAsync(string recordingId, string codecProfileKey, CancellationToken ct = default);
///
/// Get canonical variant candidates for a recording, ranked by quality.
///
Task> GetCanonicalVariantCandidatesAsync(string recordingId, CancellationToken ct = default);
///
/// Background job: recompute all canonical stats.
///
Task RecomputeAllStatsAsync(CancellationToken ct = default);
}
public class CanonicalStatsService : ICanonicalStatsService
{
private readonly IHashDbService hashDb;
private readonly ILogger log;
public async Task AggregateStatsAsync(string recordingId, string codecProfileKey, CancellationToken ct)
{
// Query all variants for this (recording, codec profile)
var variants = await hashDb.GetVariantsByRecordingAndProfileAsync(recordingId, codecProfileKey, ct);
if (variants.Count == 0)
{
return null;
}
var stats = new CanonicalStats
{
MusicBrainzRecordingId = recordingId,
CodecProfileKey = codecProfileKey,
VariantCount = variants.Count,
TotalSeenCount = variants.Sum(v => v.SeenCount),
AvgQualityScore = variants.Average(v => v.QualityScore),
MaxQualityScore = variants.Max(v => v.QualityScore),
PercentTranscodeSuspect = (variants.Count(v => v.TranscodeSuspect) / (double)variants.Count) * 100.0,
LastUpdated = DateTimeOffset.UtcNow
};
// Build distributions
stats.CodecDistribution = variants.GroupBy(v => v.Codec)
.ToDictionary(g => g.Key, g => g.Count());
stats.BitrateDistribution = variants.GroupBy(v => RoundToNearestBitrate(v.BitrateKbps))
.ToDictionary(g => g.Key, g => g.Count());
stats.SampleRateDistribution = variants.GroupBy(v => v.SampleRateHz)
.ToDictionary(g => g.Key, g => g.Count());
// Identify best variant (highest quality, most seen)
var bestVariant = variants
.OrderByDescending(v => v.QualityScore)
.ThenByDescending(v => v.SeenCount)
.First();
stats.BestVariantId = bestVariant.VariantId;
stats.CanonicalityScore = ComputeCanonicalityScore(bestVariant, stats);
// Persist stats
await hashDb.UpsertCanonicalStatsAsync(stats, ct);
return stats;
}
private double ComputeCanonicalityScore(AudioVariant variant, CanonicalStats stats)
{
double score = 0.0;
// Factor 1: Quality score (0.4 weight)
score += 0.4 * variant.QualityScore;
// Factor 2: Prevalence (0.3 weight)
double prevalence = variant.SeenCount / (double)Math.Max(1, stats.TotalSeenCount);
score += 0.3 * prevalence;
// Factor 3: Not transcode suspect (0.2 weight)
score += variant.TranscodeSuspect ? 0.0 : 0.2;
// Factor 4: Consensus (0.1 weight)
// If many variants exist with similar quality, reduce score
int similarQualityCount = stats.VariantCount; // Simplified
double consensus = 1.0 / Math.Log(similarQualityCount + 1);
score += 0.1 * consensus;
return Math.Clamp(score, 0.0, 1.0);
}
public async Task> GetCanonicalVariantCandidatesAsync(string recordingId, CancellationToken ct)
{
// Get all variants for this recording across all codec profiles
var allVariants = await hashDb.GetVariantsByRecordingAsync(recordingId, ct);
// Get canonical stats for each codec profile
var statsByProfile = new Dictionary();
foreach (var variant in allVariants)
{
var profileKey = CodecProfile.FromVariant(variant).ToKey();
if (!statsByProfile.ContainsKey(profileKey))
{
statsByProfile[profileKey] = await AggregateStatsAsync(recordingId, profileKey, ct);
}
}
// Return variants sorted by canonicality score
return allVariants
.OrderByDescending(v => {
var profileKey = CodecProfile.FromVariant(v).ToKey();
return statsByProfile.GetValueOrDefault(profileKey)?.CanonicalityScore ?? 0.0;
})
.ThenByDescending(v => v.QualityScore)
.ThenByDescending(v => v.SeenCount)
.ToList();
}
}
}
```
---
## 4. Canonical-Aware Download Selection (T-402)
### 4.1. Integration with Multi-Source Downloads
```csharp
namespace slskd.Transfers.MultiSource
{
public partial class MultiSourceDownloadService
{
private readonly ICanonicalStatsService canonicalStats;
///
/// Enhanced source selection that prefers canonical variants.
///
private async Task> SelectCanonicalSourcesAsync(
ContentVerificationResult verificationResult,
CancellationToken ct)
{
if (verificationResult.BestSemanticRecordingId == null)
{
// No MBID, fall back to hash-based selection
return verificationResult.BestSources.ToList();
}
// Get canonical variant candidates for this recording
var candidates = await canonicalStats.GetCanonicalVariantCandidatesAsync(
verificationResult.BestSemanticRecordingId,
ct);
if (candidates.Count == 0)
{
// No canonical data yet, use verification result
return verificationResult.BestSources.ToList();
}
// Find sources that match top canonical variants
var bestVariant = candidates.First();
var canonicalSources = verificationResult.AllSources
.Where(s => MatchesCanonicalVariant(s, bestVariant))
.ToList();
if (canonicalSources.Count >= 2)
{
log.Information("[CANONICAL] Selected {Count} sources matching canonical variant (quality={Score:F2}, seen={Seen})",
canonicalSources.Count, bestVariant.QualityScore, bestVariant.SeenCount);
return canonicalSources;
}
// Not enough canonical sources, use semantic best
log.Information("[CANONICAL] Insufficient canonical sources, using semantic best");
return verificationResult.BestSemanticSources.ToList();
}
private bool MatchesCanonicalVariant(VerifiedSource source, AudioVariant canonical)
{
// Check if source's technical properties match canonical variant
if (source.Codec != canonical.Codec) return false;
if (source.SampleRate != canonical.SampleRateHz) return false;
if (Math.Abs(source.Bitrate - canonical.BitrateKbps) > 50) return false; // Allow 50kbps tolerance
return true;
}
///
/// Check if local library already has a sufficient variant.
///
private async Task ShouldSkipDownloadAsync(
string recordingId,
AudioVariant proposedVariant,
CancellationToken ct)
{
// Get existing local variants for this recording
var localVariants = await hashDb.GetLocalVariantsByRecordingAsync(recordingId, ct);
if (localVariants.Count == 0)
{
return false; // No local copy, proceed with download
}
// Find best local variant
var bestLocal = localVariants.OrderByDescending(v => v.QualityScore).First();
// Only download if proposed variant is meaningfully better
double improvement = proposedVariant.QualityScore - bestLocal.QualityScore;
if (improvement > 0.1) // Require at least 0.1 score improvement
{
log.Information("[CANONICAL] Downloading better variant for {RecordingId}: {OldScore:F2} → {NewScore:F2}",
recordingId, bestLocal.QualityScore, proposedVariant.QualityScore);
return false;
}
log.Information("[CANONICAL] Skipping download, local variant quality={Score:F2} is sufficient",
bestLocal.QualityScore);
return true;
}
}
}
```
### 4.2. Configuration Options
```yaml
# In slskd.yml or via Options
audio:
canonical_scoring:
enabled: true
# Prefer canonical variants by default
prefer_canonical: true
# Minimum quality score improvement to download a new variant
min_quality_improvement: 0.1
# Skip download if local variant has quality score >= this threshold
local_quality_threshold: 0.85
# Automatically replace suspected transcodes
auto_replace_transcodes: false
# Recompute canonical stats periodically
stats_recompute_interval_hours: 24
```
---
## 5. Implementation Checklist (T-400 to T-402)
### T-400: Local quality scoring for AudioVariant
- [x] Define `AudioVariant` model in `src/slskd/Audio/AudioVariant.cs`
- [x] Define `CodecProfile` model in `src/slskd/Audio/CodecProfile.cs`
- [x] Implement `QualityScorer` in `src/slskd/Audio/QualityScorer.cs`
- [x] Implement `TranscodeDetector` in `src/slskd/Audio/TranscodeDetector.cs`
- [x] Extend HashDb schema with variant columns (migration)
- [x] Update `HashDbService` to persist variant metadata
- [x] Add unit tests for scoring algorithms
- [x] Add integration tests with sample audio files
### T-401: Canonical stats aggregation
- [x] Define `CanonicalStats` model in `src/slskd/Audio/CanonicalStats.cs`
- [x] Create `CanonicalStats` database table (migration)
- [x] Implement `ICanonicalStatsService` interface
- [x] Implement `CanonicalStatsService` in `src/slskd/Audio/CanonicalStatsService.cs`
- [x] Register service in `Program.cs` DI
- [x] Add background job for periodic stats recomputation
- [x] Add API endpoint: `GET /api/audio/canonical/{recordingId}` for debugging
- [x] Add unit tests for aggregation logic
- [x] Add integration tests with mock HashDb data
### T-402: Canonical-aware download selection
- [x] Extend `MultiSourceDownloadService` with canonical selection
- [x] Implement `SelectCanonicalSourcesAsync()` method
- [x] Implement `ShouldSkipDownloadAsync()` method
- [x] Add configuration options to `Options.cs`
- [x] Update `ContentVerificationService` to include codec profile metadata
- [x] Add logging for canonical selection decisions
- [x] Update album completion UI to show canonical status
- [x] Add unit tests for source selection logic
- [x] Add integration tests for download skip logic
---
## 6. Testing Strategy
### Unit Tests
```csharp
[Fact]
public void QualityScorer_FLAC_16bit_44100_Should_Score_1_0()
{
var variant = new AudioVariant
{
Codec = "FLAC",
BitDepth = 16,
SampleRateHz = 44100,
BitrateKbps = 900,
DynamicRangeDR = 11.2,
HasClipping = false
};
var scorer = new QualityScorer();
var score = scorer.ComputeQualityScore(variant);
Assert.InRange(score, 0.95, 1.0);
}
[Fact]
public void TranscodeDetector_LowBitrateFLAC_Should_DetectTranscode()
{
var variant = new AudioVariant
{
Codec = "FLAC",
BitDepth = 16,
SampleRateHz = 44100,
BitrateKbps = 200, // Impossibly low for lossless
DynamicRangeDR = 6.1
};
var detector = new TranscodeDetector();
var (isSuspect, reason) = detector.DetectTranscode(variant);
Assert.True(isSuspect);
Assert.Contains("bitrate", reason, StringComparison.OrdinalIgnoreCase);
}
```
### Integration Tests
```csharp
[Fact]
public async Task CanonicalStatsService_Should_IdentifyBestVariant()
{
// Arrange: Insert 3 variants of same recording
var recordingId = "test-recording-123";
await hashDb.InsertVariantAsync(CreateVariant(recordingId, "FLAC", 16, 44100, 900, 0.95));
await hashDb.InsertVariantAsync(CreateVariant(recordingId, "FLAC", 16, 44100, 200, 0.40)); // Transcode
await hashDb.InsertVariantAsync(CreateVariant(recordingId, "MP3", null, 44100, 320, 0.75));
// Act
var candidates = await canonicalStats.GetCanonicalVariantCandidatesAsync(recordingId);
// Assert
Assert.Equal(3, candidates.Count);
Assert.Equal("FLAC", candidates[0].Codec);
Assert.Equal(900, candidates[0].BitrateKbps);
Assert.False(candidates[0].TranscodeSuspect);
}
```
---
## 7. Performance Considerations
1. **Lazy Computation**: Compute quality scores on-demand, not on every file operation
2. **Batch Aggregation**: Recompute canonical stats in bulk during off-peak hours
3. **Caching**: Cache `CanonicalStats` in memory for hot recordings
4. **Indexing**: Ensure proper database indexes for variant lookups by recording ID
5. **Background Jobs**: Run stat recomputation as low-priority background task
---
## 8. Future Enhancements
1. **Spectral Analysis**: Integrate FFT-based transcode detection for higher accuracy
2. **Machine Learning**: Train model on known good/bad variants to improve scoring
3. **User Feedback**: Allow users to flag transcodes to improve detection
4. **Mesh Consensus**: Aggregate quality scores from multiple slskdn nodes for better canonical identification
5. **DR Meter Integration**: Automatically compute dynamic range for all FLAC files
---
This design provides a complete roadmap for implementing canonical scoring in slskdn. All types, methods, and schemas are specified in detail for Codex to implement.