Ma Fulltext Management
Overview
Gather full texts, validate completeness, and prepare a clean manifest.
Inputs
03_screening/round-01/included.bib
Outputs
04_fulltext/manifest.csv
04_fulltext/unpaywall_results.csv (optional OA lookup)
04_fulltext/fulltext_decisions.csv (Stage 04b — full-text eligibility screening)
04_fulltext/ft_agreement.md (Stage 04b — full-text inter-rater agreement)
04_fulltext/README.md
04_fulltext/ PDF files
04_fulltext/previews/ (optional PDF image previews)
Workflow (Web-First Hybrid — Default)
⚠️ Default approach: Web-based extraction first, PDF retrieval only for gaps.
Phase 1: Web-Based Data Gathering (Default — No PDFs Needed)
- Create
04_fulltext/ and build manifest.csv with record_id, DOI, PMID, title, and access notes.
- Read from
03_screening/round-01/included.bib
- Use
references/manifest-template.csv as template
- Write to
04_fulltext/manifest.csv (columns: record_id, DOI, PMID, title, access_method, confidence_score)
- Automatically run web extraction for all included studies using Claude Code's
WebSearch and WebFetch tools:
- Query PubMed structured abstracts (
https://pubmed.ncbi.nlm.nih.gov/<pmid>/)
- Query ClinicalTrials.gov registries (
https://clinicaltrials.gov/study/<nct_id>)
- Search Europe PMC, journal supplementary materials
- Record confidence scores per field (see
references/web-extraction.md for scoring).
- Update
04_fulltext/manifest.csv (confidence_score column)
- Flag studies with confidence < 0.7 for primary outcome fields → these need PDFs.
- Mark in
04_fulltext/manifest.csv (needs_pdf = TRUE)
Phase 2: Targeted PDF Retrieval (Only for Low-Confidence Studies)
- For flagged studies only (~20-30%), query Unpaywall for OA links using
scripts/unpaywall_fetch.py via uv run.
- Use
scripts/unpaywall_fetch.py
- Read from
04_fulltext/manifest.csv (needs_pdf = TRUE rows)
- Write to
04_fulltext/unpaywall_results.csv
- Download available PDFs with
scripts/download_oa_pdfs.py.
- Use
scripts/download_oa_pdfs.py
- Write to
04_fulltext/<record_id>.pdf
- Optionally render PDF previews with
scripts/render_pdf_previews.py for visual QA.
- Use
scripts/render_pdf_previews.py
- Write to
04_fulltext/previews/<record_id>_page1.png
- Request user to manually deposit any remaining PDFs that cannot be auto-retrieved.
- Update
04_fulltext/manifest.csv (access_method = "manual")
- Run OCR only when needed and preserve original files.
Why Web-First?
- Speed: 50-70% faster than PDF-only (2-3h vs 8-12h)
- No institutional access required for Phase 1
- 90-95% completeness with hybrid approach
- PDFs are only needed for ~20-30% of studies
Resources
references/manifest-template.csv provides a manifest header.
scripts/unpaywall_fetch.py queries Unpaywall for open-access links.
scripts/analyze_unpaywall.py analyzes Unpaywall results and generates summary statistics.
scripts/download_oa_pdfs.py downloads open-access PDFs automatically from Unpaywall URLs.
scripts/render_pdf_previews.py renders PDF pages to PNG previews.
Note: Unpaywall requires UNPAYWALL_EMAIL in .env.
Note: PDF previews require pdftoppm or mutool installed.
Stage 04b: Full-Text Eligibility Screening (PRISMA Item 16)
⚠️ MANDATORY — PRISMA 2020 requires reporting the number of full-text articles excluded with reasons.
After completing full-text retrieval (Phases 1-2 above), re-screen all included studies against
the full text to confirm eligibility. This step catches issues not visible at the abstract stage
(e.g., wrong population subgroup, insufficient sample size, protocol-only publications).
Workflow
Run AI full-text screening (Reviewer 1):
uv run tooling/python/ai_screen.py --project <project-name> --stage fulltext --reviewer 1
Run AI full-text screening (Reviewer 2) for dual review:
uv run tooling/python/ai_screen.py --project <project-name> --stage fulltext --reviewer 2
Compute full-text inter-rater agreement (Cohen's kappa):
uv run ma-screening-quality/scripts/dual_review_agreement.py \
--file projects/<project-name>/04_fulltext/fulltext_decisions.csv \
--col-a FT_Reviewer1_Decision --col-b FT_Reviewer2_Decision \
--out projects/<project-name>/04_fulltext/ft_agreement.md
Resolve conflicts (if any) — update FT_Final_Decision and FT_Exclusion_Code columns.
Only studies with FT_Final_Decision = include proceed to Stage 05 (data extraction).
Output Schema (fulltext_decisions.csv)
| Column |
Description |
record_id |
Matches manifest.csv and screening decisions |
title |
Study title |
doi |
Digital Object Identifier |
pmid |
PubMed ID |
FT_Reviewer1_Decision |
include / exclude |
FT_Reviewer1_Reason |
Reason with exclusion code reference |
FT_Reviewer2_Decision |
include / exclude |
FT_Reviewer2_Reason |
Reason with exclusion code reference |
FT_Final_Decision |
include / exclude (resolved) |
FT_Exclusion_Code |
Exclusion code (P1, S2, etc.) or NONE |
Exclusion Codes
Reuses standard codes from ma-screening-quality/references/screening-labels.md:
P1/P2 (population), I1/I2 (intervention), C1 (comparator), S1-S4 (study design),
O1/O2 (outcomes), T1/T2 (time), L1 (language), D1 (duplicate).
QA Thresholds
- Full-text kappa ≥ 0.60 (same threshold as abstract screening)
- All exclusions must have a documented reason and code
FT_Exclusion_Code feeds directly into PRISMA flow diagram item 16
Validation
- Ensure every included record has a matching full-text file or a documented reason for absence.
- Ensure
record_id continuity with screening decisions.
- Ensure
fulltext_decisions.csv exists before proceeding to Stage 05.
- Ensure all
FT_Final_Decision values are resolved (no blanks) before extraction.
Pipeline Navigation
| Step |
Skill |
Stage |
| Prev |
/ma-screening-quality |
03 Screening & Quality |
| 04b |
(this skill) |
Full-text eligibility screening |
| Next |
/ma-data-extraction |
05 Data Extraction |
| All |
/ma-end-to-end |
Full pipeline orchestration |
1---2name: ma-fulltext-management3description: Collect and manage full-text PDFs for included studies, track provenance, and prepare documents for extraction. Use when moving from screening to data extraction.4---56# Ma Fulltext Management78## Overview910Gather full texts, validate completeness, and prepare a clean manifest.1112## Inputs1314- `03_screening/round-01/included.bib`1516## Outputs1718- `04_fulltext/manifest.csv`19- `04_fulltext/unpaywall_results.csv` (optional OA lookup)20- `04_fulltext/fulltext_decisions.csv` (Stage 04b — full-text eligibility screening)21- `04_fulltext/ft_agreement.md` (Stage 04b — full-text inter-rater agreement)22- `04_fulltext/README.md`23- `04_fulltext/` PDF files24- `04_fulltext/previews/` (optional PDF image previews)2526## Workflow (Web-First Hybrid — Default)2728⚠️ **Default approach**: Web-based extraction first, PDF retrieval only for gaps.2930### Phase 1: Web-Based Data Gathering (Default — No PDFs Needed)31321. Create `04_fulltext/` and build `manifest.csv` with `record_id`, DOI, PMID, title, and access notes.33 - Read from `03_screening/round-01/included.bib`34 - Use `references/manifest-template.csv` as template35 - Write to `04_fulltext/manifest.csv` (columns: record_id, DOI, PMID, title, access_method, confidence_score)362. **Automatically run web extraction** for all included studies using Claude Code's `WebSearch` and `WebFetch` tools:37 - Query PubMed structured abstracts (`https://pubmed.ncbi.nlm.nih.gov/<pmid>/`)38 - Query ClinicalTrials.gov registries (`https://clinicaltrials.gov/study/<nct_id>`)39 - Search Europe PMC, journal supplementary materials403. Record confidence scores per field (see `references/web-extraction.md` for scoring).41 - Update `04_fulltext/manifest.csv` (confidence_score column)424. Flag studies with confidence < 0.7 for primary outcome fields → these need PDFs.43 - Mark in `04_fulltext/manifest.csv` (needs_pdf = TRUE)4445### Phase 2: Targeted PDF Retrieval (Only for Low-Confidence Studies)46475. For flagged studies only (~20-30%), query Unpaywall for OA links using `scripts/unpaywall_fetch.py` via `uv run`.48 - Use `scripts/unpaywall_fetch.py`49 - Read from `04_fulltext/manifest.csv` (needs_pdf = TRUE rows)50 - Write to `04_fulltext/unpaywall_results.csv`516. Download available PDFs with `scripts/download_oa_pdfs.py`.52 - Use `scripts/download_oa_pdfs.py`53 - Write to `04_fulltext/<record_id>.pdf`547. Optionally render PDF previews with `scripts/render_pdf_previews.py` for visual QA.55 - Use `scripts/render_pdf_previews.py`56 - Write to `04_fulltext/previews/<record_id>_page1.png`578. Request user to manually deposit any remaining PDFs that cannot be auto-retrieved.58 - Update `04_fulltext/manifest.csv` (access_method = "manual")599. Run OCR only when needed and preserve original files.6061### Why Web-First?6263- **Speed**: 50-70% faster than PDF-only (2-3h vs 8-12h)64- **No institutional access required** for Phase 165- **90-95% completeness** with hybrid approach66- PDFs are only needed for ~20-30% of studies6768## Resources6970- `references/manifest-template.csv` provides a manifest header.71- `scripts/unpaywall_fetch.py` queries Unpaywall for open-access links.72- `scripts/analyze_unpaywall.py` analyzes Unpaywall results and generates summary statistics.73- `scripts/download_oa_pdfs.py` downloads open-access PDFs automatically from Unpaywall URLs.74- `scripts/render_pdf_previews.py` renders PDF pages to PNG previews.75 Note: Unpaywall requires `UNPAYWALL_EMAIL` in `.env`.76 Note: PDF previews require `pdftoppm` or `mutool` installed.7778## Stage 04b: Full-Text Eligibility Screening (PRISMA Item 16)7980⚠️ **MANDATORY** — PRISMA 2020 requires reporting the number of full-text articles excluded with reasons.8182After completing full-text retrieval (Phases 1-2 above), re-screen all included studies against83the full text to confirm eligibility. This step catches issues not visible at the abstract stage84(e.g., wrong population subgroup, insufficient sample size, protocol-only publications).8586### Workflow87881. Run AI full-text screening (Reviewer 1):89 ```bash90 uv run tooling/python/ai_screen.py --project <project-name> --stage fulltext --reviewer 191 ```92932. Run AI full-text screening (Reviewer 2) for dual review:94 ```bash95 uv run tooling/python/ai_screen.py --project <project-name> --stage fulltext --reviewer 296 ```97983. Compute full-text inter-rater agreement (Cohen's kappa):99 ```bash100 uv run ma-screening-quality/scripts/dual_review_agreement.py \101 --file projects/<project-name>/04_fulltext/fulltext_decisions.csv \102 --col-a FT_Reviewer1_Decision --col-b FT_Reviewer2_Decision \103 --out projects/<project-name>/04_fulltext/ft_agreement.md104 ```1051064. Resolve conflicts (if any) — update `FT_Final_Decision` and `FT_Exclusion_Code` columns.1071085. Only studies with `FT_Final_Decision = include` proceed to Stage 05 (data extraction).109110### Output Schema (`fulltext_decisions.csv`)111112| Column | Description |113|--------|-------------|114| `record_id` | Matches manifest.csv and screening decisions |115| `title` | Study title |116| `doi` | Digital Object Identifier |117| `pmid` | PubMed ID |118| `FT_Reviewer1_Decision` | include / exclude |119| `FT_Reviewer1_Reason` | Reason with exclusion code reference |120| `FT_Reviewer2_Decision` | include / exclude |121| `FT_Reviewer2_Reason` | Reason with exclusion code reference |122| `FT_Final_Decision` | include / exclude (resolved) |123| `FT_Exclusion_Code` | Exclusion code (P1, S2, etc.) or NONE |124125### Exclusion Codes126127Reuses standard codes from `ma-screening-quality/references/screening-labels.md`:128P1/P2 (population), I1/I2 (intervention), C1 (comparator), S1-S4 (study design),129O1/O2 (outcomes), T1/T2 (time), L1 (language), D1 (duplicate).130131### QA Thresholds132133- Full-text kappa ≥ 0.60 (same threshold as abstract screening)134- All exclusions must have a documented reason and code135- `FT_Exclusion_Code` feeds directly into PRISMA flow diagram item 16136137## Validation138139- Ensure every included record has a matching full-text file or a documented reason for absence.140- Ensure `record_id` continuity with screening decisions.141- Ensure `fulltext_decisions.csv` exists before proceeding to Stage 05.142- Ensure all `FT_Final_Decision` values are resolved (no blanks) before extraction.143144## Pipeline Navigation145146| Step | Skill | Stage |147| ---- | ----------------------- | ------------------------------------ |148| Prev | `/ma-screening-quality` | 03 Screening & Quality |149| 04b | (this skill) | Full-text eligibility screening |150| Next | `/ma-data-extraction` | 05 Data Extraction |151| All | `/ma-end-to-end` | Full pipeline orchestration |