@@ -7,15 +7,19 @@ Optional, separately deployed direct-download discovery providers for
77
88This repository provides the version-one Pullbox direct-download protocol,
99Python DTO package, compatibility policy, conformance runner, synthetic
10- reference provider, and the official GetComics and Anna's Archive providers.
11- Production images are independently versioned, multi-architecture, scanned,
12- signed, and published to GHCR and Docker Hub.
10+ reference provider, the official GetComics and Anna's Archive providers, and a
11+ release-gated LibGen community provider. Published production images are
12+ independently versioned, multi-architecture, scanned, signed, and available
13+ from GHCR and Docker Hub.
1314
1415## Source Providers
1516
1617- GetComics: metadata discovery and stateless artifact-route normalization.
1718- Anna's Archive: metadata discovery with opt-in member fast-download
1819 resolution; a member secret is required only by the resolve operation.
20+ - LibGen: bounded HTML discovery, keyed metadata enrichment, and same-source
21+ generic HTTPS resolution with an editable validated source origin. Its image
22+ remains independently gated until the LibGen release decision is approved.
1923
2024Each provider will run as an independent, stateless OCI service and implement a
2125versioned, language-neutral Pullbox provider contract.
@@ -38,6 +42,7 @@ providers/
3842 synthetic/
3943 getcomics/
4044 annas_archive/
45+ libgen/
4146tests/
4247 conformance/
4348 fixtures/
@@ -66,7 +71,7 @@ coverage gate. `make docker-conformance` builds the digest-pinned synthetic
6671image and proves the protocol over an internal-only Docker network.
6772` make security-check ` runs Bandit and a strict dependency audit.
6873
69- The source-provider Compose harness builds both providers, waits for
74+ The source-provider Compose harness builds all source providers, waits for
7075process-only socket healthchecks, and validates authenticated manifests over an
7176internal-only network. Process healthchecks intentionally do not call upstream
7277sources. The harness uses generated test credentials and performs no live
@@ -80,7 +85,7 @@ Pull requests run four stable aggregate checks: `CI Required`,
8085default permissions. The security gate includes Gitleaks, strict Python
8186dependency auditing, Bandit, dependency review, and CodeQL's extended security
8287queries scoped to shipped provider code. Container checks build and smoke-test
83- all three runtime images, scan them with Grype, and prove Linux AMD64 and ARM64
88+ all four runtime images, scan them with Grype, and prove Linux AMD64 and ARM64
8489builds without publishing.
8590
8691High and Critical findings inherited from the pinned public Python base image
@@ -126,6 +131,29 @@ the allowlisted native control types in the contract. Pullbox validates those
126131controls, renders its own settings UI, and rejects provider-supplied HTML,
127132JavaScript, or unknown configuration fields.
128133
134+ ### Native Provider Configuration
135+
136+ Provider settings use a closed, documented vocabulary:
137+
138+ - ` enum ` declares closed choices. The configured value must be one of the
139+ declared values.
140+ - ` x-pullbox-suggestions ` declares editable HTTPS origin suggestions. A user may
141+ enter another safe public HTTPS origin because the list is not an allowlist.
142+ - ` x-pullbox-source-origin ` marks a field as the provider's effective source
143+ origin for provider-scoped link and browser-resolver policy.
144+
145+ Suggestions and source-origin marking are independent controls. A provider may
146+ offer editable suggestions without changing its source origin, or allow a custom
147+ source origin without supplying suggestions. Pullbox validates suggested and
148+ default origins before rendering or saving them and validates the selected
149+ origin again before use.
150+
151+ Search candidates may include an optional content fingerprint formatted as
152+ ` md5:<32 lowercase hexadecimal characters> ` . It must remain stable only while
153+ the candidate bytes are identical; changed bytes require a new fingerprint.
154+ Pullbox uses it only for deduplication and fallback grouping, never as a security
155+ or authenticity checksum, and does not treat it as durable library metadata.
156+
129157## Source Provider Behavior
130158
131159### GetComics
@@ -141,8 +169,8 @@ after a recognized challenge. It never downloads or proxies artifact bytes.
141169The Anna's Archive provider is an explicit opt-in integration. Its configurable
142170official URL accepts only ` https://annas-archive.gl ` ,
143171` https://annas-archive.pk ` , or ` https://annas-archive.gd ` . Pullbox renders the
144- field as an editable URL input with those exact choices suggested ; lookalike and
145- arbitrary domains remain rejected. Unattended resolution requires the user's
172+ field as a closed selector with those exact choices; lookalike and arbitrary
173+ domains remain rejected. Unattended resolution requires the user's
146174member fast-download secret; free slow-download automation, CAPTCHA bypass,
147175unofficial domains, and payload proxying are not supported.
148176
@@ -153,6 +181,22 @@ quota, source availability, and malformed responses remain distinct failures.
153181Opening search-result details must not call resolve because a fast-link request
154182may consume source quota.
155183
184+ Search attempts the selected official Anna's Archive page first. When that page
185+ is blocked by a browser challenge, is temporarily unavailable, or returns no
186+ candidates, the provider performs a bounded fallback against the LibGen comics
187+ catalog. Only candidates with a matching lowercase LibGen ID and MD5 content
188+ fingerprint are considered for Anna's Archive discovery, with canonical files
189+ listed before mobile derivatives. Catalog presence does not guarantee that Anna
190+ offers a member fast-download route, so availability is verified only when the
191+ user grabs the result. Catalog-derived candidates intentionally do not expose a
192+ cross-provider fingerprint to Pullbox: if Anna cannot resolve the record,
193+ Pullbox reports that failure instead of silently downloading it from LibGen.
194+ Resolution still uses the official member fast-download JSON API, and the member
195+ secret is never sent to LibGen. This fallback covers only Anna's Archive records
196+ sourced from LibGen and does not claim parity with Anna's Archive's complete
197+ catalog. The Anna's Archive image includes the catalog-discovery dependency and
198+ does not require a separate LibGen provider container.
199+
156200Successful resolves may report provider-generic remaining/limit/window quota
157201telemetry. The response intentionally excludes account identity and download
158202history. Pullbox stores only the latest capacity observation, applies its
@@ -161,6 +205,22 @@ accepted source when Anna's Archive is unavailable. Manual grabs may use the
161205reserved slots. Quota errors may include a bounded ` retry_after_seconds ` hint
162206so Pullbox can recover automatically even without an earlier capacity report.
163207
208+ ### LibGen
209+
210+ The LibGen provider is a separately packaged community integration. It accepts
211+ the documented LibGen origins as editable suggestions, validates the selected
212+ public HTTPS origin before every operation, and attempts ordinary HTTP before
213+ using a request-scoped browser resolver for a recognized source gate. Search is
214+ bounded to three query variants and keyed metadata enrichment; positive and
215+ negative caches are process-local and bounded.
216+
217+ Candidate and artifact identity are revalidated by lowercase MD5, keyed file
218+ metadata, and edition relationships before a same-source public HTTPS artifact
219+ is returned. The MD5 is content identity and deduplication evidence, not a
220+ security guarantee. The provider does not proxy payload bytes, retain resolver
221+ cookies, expose full artifact URLs in logs, or reuse Anna's Archive links.
222+ Known-source failover is bounded to one alternate origin per operation.
223+
164224## Deployment And Registration
165225
166226Provider services are deployed separately from Pullbox. An operator creates a
@@ -187,8 +247,11 @@ either registry; both names resolve to the same signed digest.
187247
188248| Provider | GHCR | Docker Hub |
189249| --- | --- | --- |
190- | GetComics | ` ghcr.io/pullboxapp/pullbox-provider-getcomics:1.0.0 ` | ` docker.io/pullbox/pullbox-provider-getcomics:1.0.0 ` |
191- | Anna's Archive | ` ghcr.io/pullboxapp/pullbox-provider-annas-archive:1.0.0 ` | ` docker.io/pullbox/pullbox-provider-annas-archive:1.0.0 ` |
250+ | GetComics | ` ghcr.io/pullboxapp/pullbox-provider-getcomics:1.0.2 ` | ` docker.io/pullbox/pullbox-provider-getcomics:1.0.2 ` |
251+ | Anna's Archive | ` ghcr.io/pullboxapp/pullbox-provider-annas-archive:1.0.1 ` | ` docker.io/pullbox/pullbox-provider-annas-archive:1.0.1 ` |
252+
253+ LibGen image publication is intentionally omitted from this table until its
254+ independent release gate is approved and a numbered provider release exists.
192255
193256Pin a numbered version or the immutable digest in production. ` latest ` tracks
194257only the newest stable provider release; prerelease and manual ` edge ` builds do
0 commit comments