4.7 KiB
4.7 KiB
Quality gates — jamendo provider
Gates for the /jamendo provider (architecture/jamendo-provider.md). Automatic
tests live inline in jamendody/src/tests.rs (unit, over a FakeJam) and are
named in each gate. LLM gates are read-and-reason checks an implementing agent
verifies.
Automatic tests (jamendody/src/tests.rs)
- T1
root_has_only_search—get_lib_rootexposes exactly one child,/jamendo/search(creatable), and the root is not queueable. (D3) - T2 path parsing (
*_parse,foreign_and_malformed_paths_reject) —/jamendo,/jamendo/search,/jamendo/search/<term>,/jamendo/track/<id>,/jamendo/album/<id>parse to their variants; foreign roots, empty segments, wrong arity, and unknown tags areMalformedPath. (D3) - T3
is_track_path_only_for_canonical_track— true only for/jamendo/track/<id>; false for albums, search nodes, root. (D3/D4) - T4
search_term_lists_tracks_and_albums— a search node carries matching tracks as rows at canonical/jamendo/track/<id>paths and matching albums as queueable container children at/jamendo/album/<id>; the node is queueable andis_downloadable. (D3/D4) - T5
album_node_lists_tracks—/jamendo/album/<id>lists the album's tracks as canonical rows; node is queueable + downloadable. (D3) - T6
get_urls_for_track_returns_audio—get_urls_for_trackon a track path returns exactly the backendaudioURL; a non-track path isMalformedPath, not a stream. (D4) - T7
track_metadata_maps_fields—get_metadata_for_trackmapsname→title,artist_name→artist,album_name→Album.title,duration(secs)→Track.durationunchanged,provider_item_id == "track:<id>". (D4) - T8
create_rename_delete_search_term— creating a term adds an editable + deletable child under/jamendo/search; empty/whitespace title →InvalidInput; rename moves the term; delete removes it. (D3) - T9
backend_failures_are_typed— a backend whose every call errors makesget_lib_nodereturnProviderError::FetchError, never panics. (D2) - T10
settings_debug_redacts_client_id—format!("{:?}", settings)with aclient_idset does not contain the id and shows<redacted>. (D5) - T11
duration_is_seconds_not_ms— a track whose backendduration_secsis 210 yieldsTrack.duration == Some(210)(guards against a ms/seconds regression like the web bug). (D1/D4)
LLM quality gates (read-and-reason)
- G1 — no panics on external conditions. No
unwrap/expect/panic!on network, decode, config, or path input injamendody. Lock poisoning degrades to empty (unwrap_or_default), never panics. (Hard rule) - G2 — typed error boundary. Every
JamApifailure is aFetchErrorvariant; the provider maps it toProviderError(FetchError/MalformedPath/NotSupported/InvalidInput) and logs the typed cause. Nocolor-eyre/anyhowleaks across the trait. (Hard rule) - G3 — client_id is redacted everywhere.
SettingsandJamApihave hand-writtenDebugthat redactclient_id; it never appears in a log line, and a resolvedaudioURL (may carry a signed token) is never logged. (Hard rule: redact secrets) - G4 — timeouts on every external call. The
reqwestclient is built with a timeout fromcall_timeout_secs; no unbounded HTTP call exists. (Hard rule) - G5 — bounded results, no silent caps.
search_results(≤ API max 200) andalbum_tracksbound listings; when a cap truncates, it islog-ged (debug/warn), not silent. (Hard rule: no silent caps) - G6 — non-fatal init. A missing/empty
client_id(or unparseablejamendo.toml) makesinitreturn a typedConfigerror; the orchestrator maps it toNoneso only/jamendois lost, never the server. No blocking network inbuild(). (D1/D5) - G7 — canonical leaf independence. Track rows and album children always use
/jamendo/track/<id>and/jamendo/album/<id>regardless of the branch they were reached through, so playback/expansion never depends on browse context. (D3) - G8 — no proto/wire/TUI/player change. The feature is a pure path-prefix
subtree: no edit to
crabidy.proto,ProviderCommand, the TUI, oraudio-player. Search-term flows reuse the existing create/rename/delete RPCs. (Assumptions) - G9 — defensive DTOs. Wire structs use
#[serde(default)]; a missing field degrades (empty/None), a renamed field is a localJamApifix, never a crash. Ids decode whether numeric or string. (R3) - G10 — docs. Public items (
Client,Settings,PROVIDER_ROOT, theJamtrait and its methods, domain types) carry doc comments stating intent and error behavior. (Preference)