initial commit
Publish image / publish (push) Failing after 13s

This commit is contained in:
Worph
2026-07-25 21:28:35 +02:00
parent ae1db15bd2
commit c7299d549c
33 changed files with 11140 additions and 1 deletions
+98 -1
View File
@@ -1 +1,98 @@
# meta-feeder-card
# 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
```bash
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:
```json
{ "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`.