zot: PRISMA screening workflow with Zotero annotations #258
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Objective
Use Zotero highlighting and annotation tools to facilitate systematic review screening and PRISMA flow.
Workflow
screen:include,screen:exclude,screen:uncertainZotero Tools
Automation
Acceptance Criteria
Closed. LLM-driven PRISMA pipeline shipped for
skin-subs.Architecture
Model-agnostic by construction: every LLM call goes through a
Providerprotocol insrc/prisma/llm.py.AnthropicProvidertoday (Messages API, prompt caching oncache_controlmarkers);OpenAICompatProviderstub ready for vLLM/Ollama/llama.cpp-server — swap viaPRISMA_LLM_PROVIDERenv, no code change.Modules
src/prisma/llm.py—LLMCall/LLMResult/LLMToolvalue objects;Providerprotocol; Anthropic + OpenAI-compat backends. Lazy SDK imports so the corestackCLI stays importable without theprismaextras.src/prisma/project.py— project bootstrap. Three Zotero anchor items per project carry the three PRISMA documents as notes:prisma:criteria,prisma:extraction-template,prisma:reasons. Edits happen in the Zotero UI; code reads via tag lookup._LEGACY_COHORT_TAGSbackfillsproject:<name>onto legacy cohort tags (module:skin-subs→project:skin-subs) on init.src/prisma/export.py— Zotero item → YAML-frontmatter markdown. Abstract + optional PDF full text (via pdfminer → pypdf fallback) + notes + PDF annotations. Fulltext skipped at stage 2, included at stages 3/3+.src/prisma/tools.py— three JSON-schema tool definitions (SCREEN_TOOL,ELIGIBILITY_TOOL,EXTRACT_TOOL). Tools are forced responses viaLLMCall.force_tool=<name>.src/prisma/ingest.py— tool-call payload → Zotero tags + note. Tag-surgery rule enforces stage mono-assignment (strips oldstage:*before writing new).src/prisma/screen.py— stage 2 loop. Cached prefix = system + criteria + reasons; per-item tail = item markdown.src/prisma/eligibility.py— stage 3 loop. Same prefix, full-text body, resolves tostage:4-includedon include.src/prisma/extract.py— stage 3+. Cached prefix = extraction template; fillsEXTRACT_TOOLschema; writes structured note taggedprisma:extracted.src/prisma/flow.py— PRISMA 2020 Mermaid diagram + text summary from tag counts. No LLM calls.Tag vocabulary
CLI
Verified e2e
init skin-subs→ 3 anchors + 10,262 items backfilled withproject:skin-subsscreen --limit 5→ 5 screened (2 exclude:editorial,wrong-population; 3 uncertain); themes discovered (amniotic-membrane,ocular-surface,diabetic-foot-ulcer,dermagraft,apligraf, etc.)eligible --limit 2→ 2 assessed, gracefullyunavailable-fulltextwhen PDFs missingflow→ Mermaid flowchart from live tag countsKnown follow-ups (not blocking)
prisma run skin-subsinto a cron via issue #343's scheduler once that lands.prisma export-extractedCLI that aggregatesprisma:extractednotes into an analysis-ready Parquet for #246's manuscript analysis.OpenAICompatProvideronce a local vLLM/Ollama endpoint is stood up.Files added