TMDB knows what airs today; asking the indexers instead would mean one query per show per day, which is the load that wedges a Prowlarr. So the row is bounded by air date: TV to the single day, film to a fortnight (a day of cinema releases is usually empty). The vote floor is lifted on this row only — a season airing now has not collected 50 votes yet, and the shared floor would empty exactly the row it is meant to fill. The bound is computed per request, so the row rolls over at midnight with nothing scheduled.
meta-feeder-card
The card tier feeder for the MetaMesh gateway — the discovery half of gateway search.
A card is a metadata-only record identifying a work (a series, a film), not a file: title, poster, description, and an id bag of every cross-source identifier the bridge could resolve. It has no bytes, and by design never will.
Phase 1 — CARD (this feeder) Phase 2 — RETRIEVAL (content feeders)
<free text> fileType:card fileType:video + the card's id bag
one cached TMDB search/multi the full indexer budget, ONE work
→ a poster grid of works → the episode / version list
── user clicks a card ──
Splitting the two halves is the point. Previously one query resolved ten speculative candidate works and searched every indexer for all of them, against a shared 1 req/s bucket — so the work the user actually wanted got a tenth of the budget. A card query touches TMDB only; the indexer budget is spent later, entirely on the card that was clicked.
Upstreams
| upstream_id | source | status |
|---|---|---|
tmdb |
themoviedb.org | shipping |
myanimelist |
myanimelist.net | planned — a sibling FeederPlugin in this same binary |
Both declare served_file_types = ["card"], which is the whole routing story:
meta-search fans a fileType:card query out to every gateway advertising it, so
adding this tier needed no meta-search change.
Card identity
A card's CID is a 0x1007 card locator — an identity-multihash CIDv1 whose
payload is varint(len(source)) ‖ source ‖ id, e.g. ("tmdb", "tv:95479").
- Deterministic in
(source, id), so any peer holding a tmdb id derives the address offline, with no discovery round-trip — and the same card found by two peers converges on one meta-core record for free. - Ranks 5 (opaque-locator tier), so it never outranks a real digest. That is what will make a future cross-source merge — one meta-core record carrying both a TMDB and a MyAnimeList locator — safe.
- Never seeded to bitswap (seeding is gated on sha2-256). Nothing to seed.
Cards are treated as immutable: no TTL, no refresh, and no drifting values (rating, popularity) stored on them. Growth is append-only — a future season card is an addition beside the series card, never an edit to it.
Config
Per-plugin config lives on the feeder (gateway invariant 12), served as a
schema-driven form at GET /config:
| key | meaning |
|---|---|
tmdb_token |
TMDB v4 read token. Required — without it the feeder soft-skips (stays healthy, returns no cards). |
tmdb_rate_per_sec |
Sustained TMDB request rate. Default 20/s. |
tmdb_burst |
Short-burst token ceiling. Default 20. |
card_top_n |
Works returned per free-text search. Default 10. Costs no indexer requests. |
Env (TMDB_TOKEN, TMDB_RATE_PER_SEC, TMDB_BURST, CARD_TOP_N) seeds the
first boot; the config file wins from then on. No hot reload — bounce the feeder.
Build / run
cargo build --release --bin card-feeder
cargo test -p card-feeder
# Image (build context is the repo root so the vendored SDK path dep resolves)
docker build -f feeder-plugin/card-feeder/Dockerfile -t ghcr.io/worph/meta-feeder-card:dev .
Register it with a gateway by adding it to that gateway's gateway-config.json
feeders map (or via the dashboard) and restarting:
{ "feeders": { "card-feeder": { "url": "http://card-feeder-hub:8080" } } }
Layout
crates/meta-feeder-sdk/ vendored SDK copy (mirrored from meta-gateway)
feeder-plugin/card-feeder/
src/tmdb.rs the FeederPlugin impl — routing + query + outcomes
src/card.rs the Card model + its DiscoveryRecord projection
src/resolve.rs cache- and budget-gated TMDB resolution
src/tmdb_client.rs TMDB v3 HTTP client + DTOs
src/tmdb_budget.rs token bucket
src/consts.rs
Design rationale, including what was deliberately not built:
meta-gateway/docs/others/card-tier-search.md.