From research-papers
Rebuilds propstore knowledge store from academic papers directory with notes.md and claims.yaml. Four-phase pipeline: per-paper finalize, concept alignment, promote, cross-paper stances, builds sidecar.
npx claudepluginhub ctoth/research-papers-plugin --plugin research-papersThis skill uses the workspace's default tool permissions.
Rebuild a propstore knowledge store from scratch using a collection of papers that already have notes.md and claims.yaml.
Retrieves scientific papers by URL, DOI, or title, extracts structured notes, concepts, claims, and justifications, then ingests into propstore via nested skills.
Builds Wikipedia-style Obsidian vaults from academic PDFs, extracting concepts into linked notes with atomic sentences and citations. Expands existing networks with new papers.
Extracts claims, figures, and evidence from academic paper drafts (Word, LaTeX, Markdown, Obsidian folders) plus Zotero metadata into .paper/claims.yml and figures.yml for AI writing skills.
Share bugs, ideas, or general feedback.
Rebuild a propstore knowledge store from scratch using a collection of papers that already have notes.md and claims.yaml.
paper.pdf, notes.md, metadata.jsonpks CLI available (propstore installed)--fresh is specifiedpapers_dir="$ARGUMENTS"
knowledge_dir="${papers_dir}/../knowledge" # default: sibling of papers dir
ls "$papers_dir"/*/notes.md | head -20
List all paper directories with their artifact status:
for d in "$papers_dir"/*/; do
name=$(basename "$d")
notes=$([ -f "$d/notes.md" ] && echo "Y" || echo "N")
claims=$([ -f "$d/claims.yaml" ] && echo "Y" || echo "N")
justs=$([ -f "$d/justifications.yaml" ] && echo "Y" || echo "N")
stances=$([ -f "$d/stances.yaml" ] && echo "Y" || echo "N")
echo "$name notes=$notes claims=$claims justifications=$justs stances=$stances"
done
# Delete old knowledge store if it exists
rm -rf "$knowledge_dir"
pks init "$knowledge_dir"
Verify:
ls "$knowledge_dir"/.git 2>/dev/null && echo "Propstore initialized"
pks form list
Each paper gets its own isolated source branch. There are no cross-paper dependencies in this phase, so if subagents are available, dispatch one subagent per paper and run them all in parallel. Each subagent runs steps 2a–2f independently for its paper. If subagents are not available, run the steps sequentially for each paper.
Do not proceed to Phase 2 until every paper has either finalized successfully or reported a blocker.
For each paper directory:
source_name=$(basename "$paper_dir")
# Read metadata.json for origin type and value
pks source init "$source_name" --kind academic_paper \
--origin-type <doi|arxiv|url|file> --origin-value "<value>" \
--content-file "$paper_dir/paper.pdf"
pks source write-notes "$source_name" --file "$paper_dir/notes.md"
pks source write-metadata "$source_name" --file "$paper_dir/metadata.json"
/research-papers:extract-claims <paper_dir>
This writes claims.yaml. The skill may attempt pks source add-claim — that will fail because concepts aren't registered yet. This is expected. The important output is claims.yaml on disk.
/research-papers:register-concepts <paper_dir>
This runs propose_concepts.py pks-batch to extract concept names from claims.yaml, then the agent enriches definitions and assigns forms. Output: <paper_dir>/concepts.yaml. The skill ingests via pks source add-concepts.
Now that concepts are on the source branch, ingest claims:
source_name=$(basename "$paper_dir")
pks source add-claim "$source_name" --batch "$paper_dir/claims.yaml"
If add-claim fails with "unknown concept reference(s)": the error lists the specific missing names. Add those concepts to concepts.yaml, re-run pks source add-concepts, retry add-claim. Iterate until add-claim succeeds.
/research-papers:extract-justifications <paper_dir>
The skill writes justifications.yaml and ingests via pks source add-justification.
pks source finalize "$source_name"
Check the finalize report. Status must be "ready" before proceeding. If "blocked", fix the reported errors and re-finalize.
Do NOT add stances yet. Cross-paper stances require target claims to be on master, which happens after Phase 3.
After all papers are finalized, align concepts across source branches. This puts canonical concepts on master, which is required before source branch promotion.
# Build the list of source branches
branches=""
for d in "$papers_dir"/*/; do
branches="$branches source/$(basename $d)"
done
pks concept align $branches
This produces alignment artifacts grouping concepts by name overlap.
# List alignment artifacts
pks concept show align:<cluster_id>
For each cluster, the agent reviews:
pks concept decide <cluster_id> --accept <best_id> --reject <other_ids>
pks concept promote-alignment <cluster_id>
Repeat for each cluster. After all clusters are promoted, canonical concepts are on master with artifact_ids.
Report:
With concepts on master, source branches can now be promoted. This puts claims on master with logical IDs, which enables cross-paper stance references.
for d in "$papers_dir"/*/; do
source_name=$(basename "$d")
pks source promote "$source_name" 2>&1 || echo "FAILED: $source_name"
done
If promote fails with "unresolved concept mappings": the listed concept handles don't have corresponding master concepts. Check concept alignment — some clusters may not have been decided/promoted. Fix and retry.
After this phase, all claims are on master. Cross-paper claim references (e.g., Bowman_2018_EffectsAspirinPrimaryPrevention:claim11) resolve via master logical IDs.
Now extract stances that reference claims across papers, re-finalize to validate the cross-references, and re-promote to include stances on master.
Read all papers' citations.md and notes.md Cross-References sections:
for d in "$papers_dir"/*/; do
echo "=== $(basename $d) ==="
grep -A 20 "## Collection Cross-References" "$d/notes.md" 2>/dev/null
echo "---"
done
Identify argumentative clusters — groups of papers that:
Papers may appear in multiple clusters.
If subagents are available, dispatch one subagent per argumentative cluster in parallel. Each subagent extracts stances for the papers in its cluster. If subagents are not available, run sequentially per cluster.
For each cluster:
/research-papers:extract-stances <paper_dir> --cluster paper1,paper2,paper3
The agent reads all claims within its cluster and extracts stances for each paper. Stances go into standalone stances.yaml files.
Do not proceed to 5c until all stance extraction is complete.
For each paper that has stances:
source_name=$(basename "$d")
# Ingest stances to source branch
pks source add-stance "$source_name" --batch "$d/stances.yaml"
# Re-finalize (validates stance targets against master)
pks source finalize "$source_name"
# Re-promote (overwrites master with stances included)
pks source promote "$source_name"
If finalize reports stance errors: the listed targets don't resolve. Check that the target paper was promoted in Phase 3 and that the claim ID matches. The target format is PaperDirName:claimID (e.g., Bowman_2018_EffectsAspirinPrimaryPrevention:claim11).
Re-finalize is safe: it overwrites the Phase 1 finalize report on the source branch.
Re-promote is safe: it overwrites the Phase 3 master files and adds stance files.
pks build
pks world status
pks query "SELECT COUNT(*) FROM claims"
pks query "SELECT COUNT(*) FROM concepts"
pks query "SELECT conflict_type, COUNT(*) FROM conflicts GROUP BY conflict_type"
# What do we know about aspirin?
pks world query aspirin
# Explain the argumentation around a specific claim
pks world explain <claim_artifact_id>
# What conflicts exist?
pks world status
Write to reports/ingest-collection-report.md:
pks concept align with the relevant source branches, decide, promote-alignment. Retry promote.PaperDirName:claimID.pks validate for structural diagnostics. Common cause: concept form mismatch (claim references concept with incompatible form for its conditions).