pub async fn fetch_paper(
ref_: &Ref,
profile: &CapabilityProfile,
ctx: &FetchContext,
store: &dyn Store,
store_root: &Utf8Path,
) -> Result<FetchPaperOutcome, FetchError>Expand description
Resolve a Ref to a PDF (or metadata-only fallback) and write it
through store.
Binding spec: docs/MCP_TOOLS.md §4 (doiget_fetch_paper),
docs/REDIRECT_ALLOWLIST.md §3 (informed-best-effort posture for the
DOI OA PDF leg), docs/PROVENANCE_LOG.md §3 (per-attempt Fetch rows
emitted by the source impls; StoreWrite row emitted by this
orchestrator).
§Dispatch
Ref::Arxiv(_)→ArxivSource::fetch; the source returns PDF bytes + Atom-feed metadata. The orchestrator writes both the PDF and the metadata TOML.Ref::Doi(_)→ Crossref metadata + Unpaywall license/OA-URL enrichment + (when the OA URL host is on theoa-publisherallowlist) a publisher PDF leg. A failure on the PDF leg is non-fatal: the metadata is still written and the orchestrator returnsOk(...)withsourceset to the metadata source.
§Side effects
Each consulted source emits one LogEvent::Fetch row via
ctx.log.append. The orchestrator additionally emits one
LogEvent::StoreWrite row on the successful write. Session bookend
rows are the caller’s responsibility (the CLI’s
commands::fetch::run_with_options wraps the call; the MCP server’s
doiget_fetch_paper tool method wraps it too).
§Errors
Returns FetchError from the underlying Source dispatch. The
MCP boundary converts these to the closed crate::ErrorCode set
via the existing From<FetchError> for ErrorCode impl.