Roadmap¶
Guidance for contributors, not a commitment calendar. Paperful stays a local CLI: fetch missing PDFs, lint identifiers, propose metadata patches on disk, write back through a library adapter. See architecture.md.
Surfaces like a Zotero plugin, Firefox extension, or web GUI are not the
product direction. Optional thin bridges (paperful session login) capture a
local Chromium profile; they do not rewrite the fetcher.
Ambition beyond core is framed as a local research library workbench —
one catalogue, one disk ledger, one write-back bus — grown as optional modules
that speak the same adapter + state/ protocol. Do not expand that surface
until the fetch / lint / attach loop is boringly reliable. 1.0 is that loop
plus the trust checklist below — not a GUI or a second product.
0.1 → 1.0 (trust)¶
0.1 is a first usable gap-filler. Do not call it 1.0 until these land.
Do not grow this list into a second product (no GUI, no auto Sci-Hub, no
“AI fetch everything”).
Step |
UX outcome |
Status |
|---|---|---|
End-of-run one-line banner: |
Trust after a run |
Summary table ships; banner not locked |
Attachment provenance stamp ( |
Trust inside Zotero |
Not shipped |
|
Trust before network |
Shipped |
Exit 2 + next-steps when Zotero is down ( |
Fresh clone never dead-ends |
Shipped |
Slim README + CHANGELOG known limits |
Trust before install |
Shipped |
Lock |
Trust for agents |
Named schema; not frozen |
Nice-to-have (not 1.0 blockers): colour glossary next to doctor (documented);
collection picker hint on fuzzy --collection miss.
Core (keep sharpening)¶
Resumable missing-PDF fetch, source routing, circuit breaker, EZProxy / Scholar session hygiene, attach reliability,
doctor/reportDeterministic
lint/fix-metadata(Crossref / OpenAlex / Semantic Scholar / PubMed, PDF-text DOI via pdftotext then pypdf) with explicit--applyCORE as an OA PDF source when
core_api_keyis setLibrary adapter seam (
LibraryBackend); Mendeley when someone needs it
Optional LLM assist (local / LiteLLM)¶
Status: maybe later — useful, not required for the PDF loop.
MVP: when a title looks wonky (ALL CAPS, truncated, HTML junk, filename-as-title,
mojibake), propose a cleaned title using abstract and/or first-page PDF text
as grounding. Output lands in the existing patch pipeline
(state/metadata-patches.jsonl); human review + fix-metadata --apply remain
mandatory. Never mutate the library from a model call alone.
Sketch:
lint / heuristics flag bad title
→ extract abstract (item) + first-page text (pdfid / out/ cache)
→ opt-in LLM propose {title} JSON
→ validate (non-empty, length bounds, not equal to garbage patterns)
→ Patch(source="llm_title", …) beside deterministic patches
Patterns to copy (do not invent a third stack)¶
Prefer rollup’s CLI-shaped LiteLLM/Ollama split; borrow transcriptx enablement / grounding / review rules for “suggestions only.”
Sibling checkouts (not in this repo): Documents/rollup, Documents/transcriptx.
Pattern |
Draw on |
Paperful takeaway |
|---|---|---|
Optional extra, no silent cloud default |
rollup |
|
Provider protocol + Ollama vs LiteLLM clients |
|
Thin |
Reject |
|
Same guards if both providers ship |
Plan-time validation before network |
|
Fail in |
Doctor import/config checks (no paid probe) |
|
Amber/red when |
Keys from env only; |
rollup |
Document remote = title/abstract/PDF excerpt leave the machine |
Pluggable client + Null stub |
|
Fix code never imports provider SDKs directly |
Suggestions grounded + human apply |
|
Ground in abstract/first page; reject ungrounded titles; continue on failure |
Opt-in module flag separate from global LLM |
transcriptx |
e.g. |
Multi-provider stance (sidecar vs in-process) |
|
Start in-process LiteLLM like rollup; revisit sidecar only if weight hurts |
Config sketch (names TBD):
[llm]
enabled = false
provider = "ollama" # ollama | litellm
model = "qwen2.5:7b"
base_url = "http://127.0.0.1:11434"
# api_base = "" # LiteLLM / OpenAI-compatible
# allow_remote = false
[fix_metadata]
llm_title = false # MVP gate; requires [llm].enabled
Non-goals for the MVP: chat-over-library, auto-tagging everything, rewriting
abstracts, silent cloud defaults, applying patches without --apply.
Later LLM verbs (only after title MVP): venue/date cleanup from first page; “is this PDF the right work?” mismatch check; grounded briefs — still proposals on disk.
Maybe later, not core¶
Workbench layers that would broaden paperful beyond fetch/lint. Worth keeping on the map; not prerequisites for 1.x usefulness.
Catalogue unification — multi-manager adapters as equals; conflict journal; query-scoped virtual collections as run scopes
Acquire beyond journal PDFs — shipped: local session vault (
paperful session login); pluggable grey-lit PDF playbooks indirect/landingwith builtin packs (UNGA/undocs · BBNJ/DOALOS · ISA; plus FAO/OECD/IEA/WHO — extend via[[grey_playbooks]]). Still parked: SI/dataset/code siblings; watch/alert → propose items.Identity / resolver graph — work ↔ version ↔ preprint; scored patches with undo; citation ingest; manifestation-aware dedupe
File & attachment OS — linked vs stored policy, rename, orphan GC, broken-link repair, PDF quality / wrong-paper triage (eat StorScan-class tools)
Maybe later¶
Larger product bets. Park until the ledger and core loop justify them.
Reading & knowledge — local full-text index / OCR; annotation sync; evidence packs; briefs grounded only in local PDFs
Writing & export — CSL / BibLaTeX / Quarto sync; living review / gap lists; git-friendly CSL-JSON dumps
Agent surface — MCP + CLI sharing one capability API; dry-run defaults; typed source/policy permissions; playbooks
Collaboration without SaaS — shared
state/over syncthing/git; attach locks; optional headless fetch nodeCompliance & provenance — 1.0 attach stamp is listed above; later: per-PDF chain of custody, more jurisdictional presets, reproducible run records
Explicitly out of near-term scope¶
Hosted multi-user service
Replacing Zotero as a reading UI
Shipping Sci-Hub or proxy abuse as defaults (opt-in + presets stay as today)
Jeffersonian transcription / qualitative coding apps