Findings
correctness
crates/epignosis/src/identity.rs:124 — parse_filename treats two-part 'Artist - Title' filenames as unparseable and returns the full stem as title (low)
crates/epignosis/src/resolver.rs:165 — score_book_result treats None==None artist comparison as a positive author match, inflating score for author-unknown results (low)
crates/epignosis/src/resolver.rs:281 — enrich_from_canonical failure is silently discarded without logging (low)
resilience
crates/epignosis/src/cache.rs:38 — MetadataCache::get() TOCTOU race between expired-entry check and removal can evict freshly inserted replacements (low)
crates/epignosis/src/cache.rs:39 — TOCTOU race in MetadataCache::get allows concurrent insert to be silently deleted (low)
crates/epignosis/src/providers/musicbrainz.rs:84 — All provider HTTP response bodies buffered via response.text() with no size limit — OOM risk from malicious provider response (low)
crates/epignosis/src/providers/openlibrary.rs:65 — OpenLibraryProvider::fetch_work does not check HTTP status before parsing — 404 produces misleading ProviderParseSnafu error (low)
security
crates/epignosis/src/providers/musicbrainz.rs:63 — MusicBrainz Lucene query built by direct string interpolation of tag-derived title and artist, allowing query structure injection (low)
crates/epignosis/src/providers/tmdb.rs:65 — TMDB API key transmitted as URL query parameter leaks to server access logs (low)
testing
crates/epignosis/src/resolver.rs:111 — build_query has no test — tag-vs-filename fallback and album_artist preference are untested (low)
crates/epignosis/src/resolver.rs:184 — resolve_identity and enrich have no unit tests — the core identity pipeline is completely unverified (low)
Note
These are batched low/info findings; split any out if it gets prioritized.
Findings
correctness
crates/epignosis/src/identity.rs:124— parse_filename treats two-part 'Artist - Title' filenames as unparseable and returns the full stem as title (low)crates/epignosis/src/resolver.rs:165— score_book_result treats None==None artist comparison as a positive author match, inflating score for author-unknown results (low)crates/epignosis/src/resolver.rs:281— enrich_from_canonical failure is silently discarded without logging (low)resilience
crates/epignosis/src/cache.rs:38— MetadataCache::get() TOCTOU race between expired-entry check and removal can evict freshly inserted replacements (low)crates/epignosis/src/cache.rs:39— TOCTOU race in MetadataCache::get allows concurrent insert to be silently deleted (low)crates/epignosis/src/providers/musicbrainz.rs:84— All provider HTTP response bodies buffered via response.text() with no size limit — OOM risk from malicious provider response (low)crates/epignosis/src/providers/openlibrary.rs:65— OpenLibraryProvider::fetch_work does not check HTTP status before parsing — 404 produces misleading ProviderParseSnafu error (low)security
crates/epignosis/src/providers/musicbrainz.rs:63— MusicBrainz Lucene query built by direct string interpolation of tag-derived title and artist, allowing query structure injection (low)crates/epignosis/src/providers/tmdb.rs:65— TMDB API key transmitted as URL query parameter leaks to server access logs (low)testing
crates/epignosis/src/resolver.rs:111— build_query has no test — tag-vs-filename fallback and album_artist preference are untested (low)crates/epignosis/src/resolver.rs:184— resolve_identity and enrich have no unit tests — the core identity pipeline is completely unverified (low)Note
These are batched low/info findings; split any out if it gets prioritized.