3.8 KiB
Discovery Scout (deterministic first release)
The reader now has a separate Discover page. This first slice deliberately uses the curated Greatest catalog, already-cached AniList identities/relations, library metadata, each user's Greatest votes, and explicit Discover feedback. It does not call an LLM, fetch new metadata, inspect chapter/image hosters, edit a collection, or enqueue downloads. The reader remains the only writer of account and discovery state; no fourth Compose service, credential, or database is required.
Use
- Open
discover.html. Each account independently enables Personalized discovery (off by default). Reading activity is a separate opt-in. The mature-title switch only applies to candidates with a known mature tag; it is not a content-safety guarantee. - An admin presses Run discovery now on the same page. Existing suggestions remain visible until the new feed is published. Runs are bounded to 50 candidates and 20 suggestions per opted-in user, with no more than four from one period. A second concurrent run is rejected.
- A reader can open Why this is here · evidence and record Interested, Maybe, No thanks, or Hide. Feedback is private to the account. Dismissed/hidden titles disappear at once; other feedback influences the next run. The user can undo a choice by clicking its active button again.
The recommendation is an editorial lead, not an availability or edition check. The public metadata link opens the provider record; an admin still uses the existing source inspection and confirmation process to download anything. The title/year/format matching is intentionally conservative but not a verified identity merge. Missing year, cover, or status remains missing.
Data and API
data/discovery.json: atomic, reader-owned candidate and per-user feed snapshots. A previous valid version is retained asdiscovery.json.prev. A corrupt file makes reads/runs fail closed rather than overwrite it.data/db.json: consent in user settings and explicit feedback underdiscoveryFeedback. The account-deletion route removes that feedback.GET /api/discovery: caller's own feed, settings, evidence, and feedback only.POST /api/discovery/feedback: caller's candidate choice; requires opt-in.GET /api/admin/discoveryandPOST /api/admin/discovery/run: admin-only status and manual generation. A run keeps the last good feed on failure.
The job asks the private scraper state API for queued titles to avoid recommending
them. If that API is unavailable, the run still uses only cached sources; the
admin result records queueAvailable: false and queue exclusion is incomplete.
No scraper queue edit occurs.
Read-only dry run and verification
From the project directory:
node discovery/cli.js run --dry-run --data data --show
npm run test:reader
docker build -t mangacircus:discovery-test .
$env:APP_IMAGE='mangacircus:discovery-test'; npm run test:discovery-ui
The dry run reads db.json, a saved library index if present, Greatest, and
cached AniList metadata. It writes nothing and does not contact providers. The
Compose/browser suite uses a disposable data tree and queue, not the live one.
Deliberate limits and next stage
This slice has no scheduled run, external metadata discovery, LLM, admin seed form, edition-finding action, or explicit purge control for old feed snapshots. Disabling consent stops feed display and future personalized generation, but existing snapshot/feedback is retained until account deletion or a later data management feature. Candidate quality is limited by the curated list and local metadata cache. Add external public metadata feeds and optional LLM only behind the existing bounded candidate/evidence contract after this deterministic path has been used and reviewed.