Claude Skill

obsidian-paper-vault

Turn a folder of research PDFs into an Obsidian knowledge vault — consistently formatted literature notes with frontmatter, PDF embed links, and cross-referenced atomic concept notes. Use whenever the user wants PDFs converted to Obsidian notes, a batch of papers summarized into

LLM Mart · 0 points · 3 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download aperivue-medsci-skills-skills_obsidian-paper-vault-815765c.zip · 21 KB
Part of aperivue/medsci-skills — 47 skills

Install

skills CLI npx skills add https://github.com/Aperivue/medsci-skills/tree/main/skills/obsidian-paper-vault
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install aperivue-medsci-skills@llmmart
Git git clone https://github.com/Aperivue/medsci-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole aperivue/medsci-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Obsidian Paper Vault

Converts a folder of research PDFs into a two-layer Obsidian vault: literature notes (one per paper, templated) and atomic concept notes (synthesized across papers).

The rules below are not style preferences. Each one is here because its absence produced a specific, silent failure — a fabricated patient count, a broken PDF link, an empty Dataview table — in a vault of 100+ papers.

Relationship to /lit-sync

Both skills write literature and concept notes into the same vault folders. They enter from opposite ends and must not overwrite each other.

/lit-sync obsidian-paper-vault
Input Zotero collection / refs.bib a folder of PDFs
Note key citekey short descriptive title
Owns manuscript/_src/refs.bib extracted-text cache

Never overwrite an existing note. If a note for the paper already exists (by title, DOI, or citekey), report it and skip. When both skills are in play, /lit-sync notes are the bibliographic spine; this skill's notes are the read-through summaries.

Step 0: Resolve the vault layout — ask, do not assume

Establish three paths before writing anything:

  1. Vault root — from the user, or $OBSIDIAN_VAULT. Never guess a home-directory path.
  2. Literature notes folder — default Literature/. If the vault already has a folder serving this role (02_research/논문/, Papers/, 文献/), honor the existing layout rather than imposing the default.
  3. Concept notes folder — default Concepts/, same honor-what-exists rule.

For a vault whose structure is Korean, see references/locale/ko/note_templates.md — folder names and note headings in Korean, opt-in.

Also confirm PyMuPDF is available: python3 -c "import fitz; print(fitz.__version__)" (install with pip install PyMuPDF). Text extraction caches to ~/.local/cache/paper-vault-texts/ unless the user names another location.

Step 1: Pre-extract PDF text — always, for any batch

python3 scripts/extract_pdfs.py <pdf_folder> <text_cache_folder> [max_pages]

Defaults to 12 pages, which covers abstract through discussion for most papers.

Never hand a PDF path to a subagent. A subagent that cannot open a file does not report failure — it writes the note from training data, and the result is a plausible note with invented numbers. Pass the .txt paths instead. Single-paper interactive work may read the PDF directly (the Read tool handles PDFs); batches may not.

Step 2: Launch subagents in parallel

Five subagents × 5–6 papers is the working batch size: enough parallelism to clear 25 papers in one pass, small enough that per-agent quality holds. Group papers thematically per agent so each one can spot recurring concepts.

Give each subagent: its assigned text-file paths with destination filenames, the template from references/templates.md verbatim, the list of concept notes that already exist, and the prohibition on inventing anything. references/subagent-prompt.md holds the full prompt.

Step 3: Track progress in a queue file

Keep PAPER_QUEUE.md in the vault with per-paper status (done / pending / skipped / in progress) so a 200-paper vault survives across sessions. Update it after each batch.

Step 4: Extract concept notes once 10+ literature notes exist

A phrase earns a concept note when it appears in 3+ notes, carries pedagogical value, and is treated differently by different papers. Model names, datasets, and journals are entities, not concepts. See references/concept-extraction.md for the full criteria, the frequency scan, and the seedling/growing/mature lifecycle.

Roughly one new concept note per 5–7 literature notes is healthy. Faster than that is concept inflation, and it shows up as dozens of stub notes the user never edits.

Anti-Hallucination rules (non-negotiable)

A note that is fluent, correctly formatted, and wrong in its numbers is worse than no note: the user cites it. These three rules exist to make that failure impossible rather than unlikely.

  1. Numbers, authors, and dates come from the extracted text only — never from model knowledge, however familiar the paper. Well-known papers drift between versions, and that is exactly where invented values look most plausible.
  2. Subagents receive .txt paths, never PDF paths. A subagent that cannot open a file does not report the failure; it writes from training data. The text indirection is the only reliable guard.
  3. What the text does not state, the note does not claim. Write "not stated in the extracted text" instead of filling the gap.

Gate — before a batch is accepted: spot-check two notes against their text files (one sample size, one effect estimate). If either value is absent from the text, stop the batch and report it rather than continuing. This gate is the user's call to waive, not the skill's.

Structural rules

  1. Preserve the PDF filename exactly in ![[filename.pdf]]. Obsidian embeds are sensitive to case, spaces, and punctuation — take the text filename and swap .txt for .pdf, character for character.
  2. Match the frontmatter field names in references/templates.md. Dataview queries break on a renamed field, and they break by returning an empty table, not an error.
  3. Use the existing tag vocabulary (references/tag-vocabulary.md) rather than inventing top-level tags.
  4. Name notes with 3–5 keyword concepts, not the PDF's full title and not paper_001.
  5. Never overwrite an existing note — see the /lit-sync boundary above.

Gate — before concept notes are presented as done: concept notes ship as 🌱Seedling with the definition marked as a placeholder, and require user review before they count as the reader's own. Say so explicitly when handing them over.

Reference files

File Read it when
references/templates.md writing any literature or concept note
references/subagent-prompt.md launching a batch
references/concept-extraction.md extracting concepts across notes
references/tag-vocabulary.md choosing tags
references/workflow.md the user asks how the layers fit together
references/locale/ko/note_templates.md the vault is Korean-structured
assets/example_paper_note.md unsure about literature-note formatting
assets/example_concept_note.md unsure about concept-note formatting

Troubleshooting

Symptom Cause Fix
Subagent says it could not read the PDF it was given a PDF path run extract_pdfs.py, pass .txt paths
Note reads plausibly but numbers are wrong subagent wrote from training data re-run against the text file; verify n, CI, p-values
Dataview table is empty frontmatter field renamed match references/templates.md exactly
PDF embed shows a broken tile filename mismatch compare character by character, including case
Note content is generic text file is abstract-only or OCR is poor re-extract with more pages, or check the source PDF
Files (medsci-skills)
  • assets
    • example_concept_note.md 2.2 KB
      ---
      title: "Sequential decision-making"
      type: concept
      tags:
        - 🧠Concept
        - 🏥ClinicalReasoning
      aliases:
        - Sequential diagnosis
      related_papers:
        - "[[Synthetic Example: Reader-Study Evaluation of an Assistive Triage Model]]"
        - "[[Synthetic Example: Cost-Aware Diagnostic Agent]]"
        - "[[Synthetic Example: Simulated Clinic Benchmark]]"
      status: 🌱Seedling
      ---
      
      # Sequential decision-making
      
      > **This note is a formatting example.** The papers it links are synthetic. It shows what a
      > seedling concept note looks like before the reader has rewritten the definition.
      
      ## 📖 Definition, in my own words
      > 🌱 *Placeholder — drafted by the skill, awaiting the reader's own wording.*
      
      Deciding what to do next when the picture is still incomplete: order a test, ask a question,
      or commit. What separates it from one-shot diagnosis is that each step changes what the next
      step should be, so the quality of a path cannot be read off its endpoint.
      
      ## 🌐 Why it matters
      Benchmarks that score only the final answer cannot distinguish a good path from a lucky one.
      Any evaluation meant to say something about clinical use has to score the sequence.
      
      ## 📚 How different papers treat it
      - **[[Synthetic Example: Reader-Study Evaluation of an Assistive Triage Model]]**: treats the
        path as an outcome in its own right; reports where readers diverged from the model
      - **[[Synthetic Example: Cost-Aware Diagnostic Agent]]**: prices each step, so the metric is
        accuracy per unit of cost rather than accuracy alone
      - **[[Synthetic Example: Simulated Clinic Benchmark]]**: holds the environment fixed and lets
        the agent choose the order, treating step count as the difficulty axis
      
      ## 🔗 Related concepts
      - [[LLM co-pilot in medicine]] — the same question from the human side: who chooses the next step
      - [[Evaluation beyond endpoint accuracy]] (not yet written) — the measurement problem this creates
      
      ## ❓ Open questions
      - Is there a scoring rule for a diagnostic path that does not collapse back to its endpoint?
      - When a model and a reader take different paths to the same answer, which one should the
        evaluation reward?
      
      ## 📝 Update log
      - 2026-01-20: drafted from 3 papers
      
    • example_paper_note.md 2 KB
      ---
      title: "Synthetic Example: Reader-Study Evaluation of an Assistive Triage Model"
      authors: [Placeholder A, Placeholder B, Placeholder C]
      journal: "arXiv:0000.00000"
      date_published: 2026-01-15
      tags:
        - 📝Paper
        - 🤖AI/LLM
        - 🏥ClinicalReasoning
        - 📊HeadToHead
      status: 🟢Completed
      aliases:
        - Synthetic-triage-reader-study
      ---
      
      # Synthetic Example: Reader-Study Evaluation of an Assistive Triage Model
      
      > **This note is a formatting example, not a real paper.** Every value below is invented to
      > show the shape of a completed note. Nothing here should be cited.
      
      📎 **Open the PDF inside Obsidian**: ![[synthetic_triage_reader_study.pdf]]
      
      ## 📌 One-line summary
      In a synthetic 20-case reader study, an assistive model raised median reader accuracy from 7
      to 9 of 10 while leaving the rate of confidently wrong calls unchanged.
      
      ## 🎯 Background and aim
      * Earlier work reported end-point accuracy but not how readers behaved with the tool in hand
      * The paper asks whether assistance changes the reasoning path or only the final answer
      * Stated hypothesis: assistance improves accuracy without reducing overconfident errors
      
      ## 🔑 Methods and results
      1. **Design**: cross-sectional reader study, 20 vignettes, 12 readers, blinded to arm
      2. **Main results**: median score 9 of 10 assisted versus 7 unassisted (p = 0.004);
         confidently-wrong rate 15% versus 14% (not significant)
      3. **Comparison**: against unassisted readers only; no second tool was evaluated
      4. **Limitations**: authors note the vignettes were curated, the reader pool was single-site,
         and no downstream patient outcome was measured
      
      ## 💡 My reading
      * The accuracy gain and the flat error rate point the same way — assistance helps the cases
        readers were already close on, not the ones they were confidently wrong about
      * Worth checking whether our own evaluation would even detect that split, or only report the
        headline accuracy
      
      ---
      ## Related notes
      * [[MOC]]
      * [[Sequential decision-making]]
      * [[LLM co-pilot in medicine]]
      * [[Reader study design]]
      
    • example_queue.md 1.7 KB
      # PAPER_QUEUE.md — example
      
      Progress tracker for batch note-writing. Lives in the vault so a large backlog survives
      across sessions. Markers: ✅ done · 🟡 in progress · ⬜ pending · ⏭️ skipped.
      
      **Batch size**: 5 subagents × 5–6 papers. Update this file after each batch, before starting
      the next.
      
      ## Status
      
      | | Papers |
      |---|---|
      | ✅ Completed | 12 |
      | 🟡 In progress | 5 |
      | ⬜ Pending | 8 |
      | ⏭️ Skipped | 2 |
      | **Total** | **27** |
      
      ## Batch 1 — Clinical reasoning (✅ done 2026-01-18)
      
      | | Source text | Note |
      |---|---|---|
      | ✅ | `triage_reader_study.txt` | `Synthetic triage reader study.md` |
      | ✅ | `cost_aware_agent.txt` | `Cost-aware diagnostic agent.md` |
      | ✅ | `simulated_clinic_bench.txt` | `Simulated clinic benchmark.md` |
      | ⏭️ | `triage_reader_study_supplement.txt` | supplement to row 1 — no separate note |
      
      ## Batch 2 — Evaluation methodology (🟡 running)
      
      | | Source text | Note |
      |---|---|---|
      | 🟡 | `rubric_agreement.txt` | `Rubric agreement across raters.md` |
      | ⬜ | `judge_calibration.txt` | `LLM-as-judge calibration.md` |
      | ⬜ | `benchmark_contamination.txt` | `Benchmark contamination.md` |
      
      ## Batch 3 — Deployment (⬜ pending)
      
      | | Source text | Note |
      |---|---|---|
      | ⬜ | `silent_trial.txt` | `Silent-mode deployment trial.md` |
      | ⏭️ | `slides_overview.txt` | slide deck, not a paper |
      
      ## Concept extraction log
      
      - 2026-01-20: 12 notes reached → extracted `Sequential decision-making`,
        `LLM co-pilot in medicine`, `Uncertainty and hallucination` (all 🌱, awaiting the reader's edits)
      - Next pass at ~20 notes
      
      ## Notes
      
      - `benchmark_contamination.pdf` is a scan; extraction is thin. Re-extract with more pages or
        check the source before writing the note.
      
  • references
    • locale
      • ko
        • note_templates.md 3.9 KB
          # Korean (ko) locale — vault layout + note templates
          
          > Opt-in Korean variant for `obsidian-paper-vault`. The skill defaults to English folder names
          > (`Literature/`, `Concepts/`) and English note headings. Use this layout when the user's vault
          > already follows a Korean structure — the skill honors an existing layout — or when the user
          > prefers Korean notes. Mirrors the `/lit-sync` ko locale so both skills write the same vault
          > the same way.
          
          ## 폴더 구조 (한국어 vault)
          
          - 논문 노트: `02_research/논문/{짧은 제목}.md`
          - 개념 노트: `02_research/개념노트/{개념 이름}.md`
          - 생각 노트: `02_research/생각노트/` — **사용자 전용, 스킬이 쓰지 않는다**
          
          ```bash
          # 기존 논문 노트 개수 확인
          ls "$VAULT/02_research/논문/" | wc -l
          ```
          
          ## 논문 노트 템플릿 (한국어 heading)
          
          ```markdown
          ---
          title: "정확한 논문 원제목 (부제 포함)"
          authors: [저자1, 저자2, 저자3]
          journal: "저널명 또는 arXiv:XXXX.XXXXX"
          date_published: YYYY-MM-DD
          tags:
            - 📝논문
            - 🤖AI/LLM
            - 🏥ClinicalReasoning
          status: 🟢Completed
          aliases:
            - 짧은별명
          ---
          
          # 논문 제목
          
          📎 **옵시디언 내부에서 PDF 원문 열기**: ![[정확한_원본_PDF_파일명.pdf]]
          
          ## 📌 한 줄 요약
          누가, 무엇을, 어떻게, 얼마나 — 텍스트 근거로 한 문장.
          
          ## 🎯 연구 배경 및 목적
          * 기존 연구가 남긴 한계
          * 이 논문이 풀려는 문제
          * 가설 (명시되어 있으면)
          
          ## 🔑 주요 내용 및 결과
          1. **설계**: n수, 데이터셋, 평가 방법 — 텍스트에 쓰인 그대로
          2. **주요 결과**: 수치는 텍스트에 있는 것만 (예: "정확도 91.1%", "p < 0.001", "중앙값 10, IQR 9–10")
          3. **비교**: baseline 또는 경쟁 모델 대비
          4. **한계**: 저자가 명시한 것
          
          ## 💡 내 생각
          * 내 연구에 주는 함의 — 저자의 주장이 아니라 읽은 사람의 판단
          * 두 번째 함의
          
          ---
          ## 관련 노트
          * [[도메인 허브 노트]]
          * [[기존 개념 노트]]
          * [[새 개념 제안]]
          ```
          
          ## 개념 노트 템플릿 (한국어 heading)
          
          ```markdown
          ---
          title: "개념 이름"
          type: concept
          tags:
            - 🧠개념
            - (도메인 태그)
          aliases:
            - AlternativeName
          related_papers:
            - "[[논문노트1]]"
            - "[[논문노트2]]"
            - "[[논문노트3]]"
          status: 🌱Seedling
          ---
          
          # 개념 이름
          
          ## 📖 정의 (내 말로)
          교과서 정의도, 논문에서 옮긴 문장도 아닌 내가 이해한 방식. 이 절이 2층의 전부다.
          
          ## 🌐 왜 중요한가
          이 도메인에서 왜 주목할 개념인지 — 읽은 사람의 판단.
          
          ## 📚 논문별 관점
          - **[[논문A]]**: 어떻게 다루는가 (구체적 인용)
          - **[[논문B]]**: 다른 각도·방법론
          - **[[논문C]]**: 상반되거나 보완하는 입장
          
          ## 🔗 관련 개념
          - [[다른 개념]] — 어떻게 이어지는가
          - [[아직 안 쓴 개념]] — 관련은 있으나 미작성
          
          ## ❓ 열린 질문
          - 아직 답이 없는 것
          - 후속 논문이 보여줘야 할 것
          
          ## 📝 업데이트 로그
          - YYYY-MM-DD: 초안 ({N}편 기반)
          ```
          
          ## 태그 (한국어 vault)
          
          `📝논문` · `🧠개념` · `💭생각` — 나머지 기술·도메인 태그는 영문
          (`references/tag-vocabulary.md`)을 그대로 쓴다. 태그를 두 언어로 이중화하면 Dataview 쿼리가
          갈라진다.
          
          ## 파일명
          
          - 논문 노트: 핵심어 3~5개. 한글·영문 혼용 가능.
            - ✅ `순차 진단 Microsoft MAI-DxO.md`
            - ❌ PDF 원제목 그대로 / `paper_001.md`
          - 개념 노트: 한글 개념명 + 통용 영문이 있으면 괄호 병기.
            - ✅ `순차적 의사결정 (Sequential Decision-Making).md`
            - ❌ `의사결정.md` (너무 일반적) / `SDM.md` (약어만)
          
          ## 주의
          
          영문판 규칙은 그대로 적용된다 — 텍스트 파일에 없는 숫자·저자·날짜를 쓰지 않을 것, PDF 파일명을
          글자 그대로 옮길 것, frontmatter 필드명을 바꾸지 말 것, 기존 노트를 덮어쓰지 말 것.
          
    • concept-extraction.md 3.6 KB
      # Extracting Atomic Concept Notes
      
      Literature notes capture what each paper said. Concept notes hold what the reader now
      understands across papers. The second layer is where a vault stops being an archive.
      
      ## When
      
      Once **10+ literature notes** exist. Below that there is nothing to cross-reference, and the
      notes produced are definitions rather than syntheses.
      
      Natural triggers: the user asks what concepts to pull out; a batch just finished; three or
      more notes circle the same unlinked idea; the user is preparing to write.
      
      ## What qualifies
      
      A phrase earns a concept note when all five hold:
      
      1. It appears in **3+ literature notes**
      2. Someone could **learn something** from the note
      3. Different papers **treat it differently** — there is something to compare
      4. It is **stable**, not a passing label
      5. It needs **synthesis**, not a definition lookup
      
      Entities fail criterion 5 and should not become concept notes: model names (GPT-4, Claude),
      datasets (MedQA), journals, organizations, evaluation formats. They are references, and a
      note about one is a stub that never grows.
      
      Borderline: technique names. `chain of thought` works as a concept if the vault holds papers
      that disagree about it; it is a stub if they merely use it.
      
      ## Process
      
      **1. Scan for recurring links and terms**
      
      ```bash
      grep -ho "\[\[[^]]*\]\]" <vault>/Literature/*.md | sort | uniq -c | sort -rn | head -30
      ```
      
      Or have a subagent read the literature notes and report term frequency with the notes each
      term came from.
      
      **2. Filter** — drop entities, keep what passes all five criteria.
      
      **3. Draft** — one note per candidate, following `templates.md`: the papers it draws on, a
      synthesized definition, a comparison of how each paper treats it, and two or three open
      questions.
      
      **4. Hand back for the user's own edit.** Present drafts and say plainly that the definition
      section is a placeholder until the user rewrites it. A concept note the user has not touched
      is still a summary wearing a concept note's frontmatter.
      
      ## Growth stages
      
      ```
      🌱 Seedling   →   🌿 Growing    →   🌳 Mature
        ~3 papers       5–10 papers       10+ papers
        AI-drafted      user-edited       user's own position
      ```
      
      Every note this skill creates starts at 🌱Seedling. Only the user's edits move it along.
      
      ## Guarding against sprawl
      
      Roughly **one concept note per 5–7 literature notes** is healthy. Warning signs:
      
      - Dozens of concept notes and none the user has edited — slow down
      - Many concepts linked from a single paper — wait for corroboration
      - Near-duplicates (`CoT`, `CoT reasoning`, `Chain-of-Thought`) — merge them
      
      ## Worked example
      
      Ten medical-AI papers, with the concepts each literature note mentions:
      
      | Literature note | Concepts mentioned |
      |---|---|
      | AgentClinic | sequential decision-making, multi-agent, bias simulation |
      | GPT-4 RCT | management reasoning, LLM co-pilot, clinical trial |
      | Med-Gemini | uncertainty-guided search, multimodal, RAG |
      | AMIE DDx | differential diagnosis, OSCE, self-play |
      | MAI-DxO | sequential diagnosis, cost-aware, multi-agent |
      | R-IDEA | clinical reasoning, physician comparison |
      | Medprompt | prompt engineering, few-shot, ensemble |
      | MAIRA-2 | radiology report, grounded generation |
      | HealthBench | physician rubric, LLM-as-judge |
      | Reasoning-model CPC | reasoning models, case conference |
      
      **Extracted** (3+ appearances, all five criteria): sequential decision-making; management
      reasoning; LLM co-pilot in medicine; uncertainty and hallucination; healthcare benchmarking;
      multi-agent systems.
      
      **Not extracted** (entities): GPT-4, o1, Med-PaLM 2; MedQA, NEJM CPC; OSCE; Google, Microsoft.
      
    • subagent-prompt.md 3.3 KB
      # Subagent Prompt for Batch Note Writing
      
      Reusable prompt for converting extracted PDF text into literature notes. Five subagents ×
      5–6 papers each is the working batch; launch them in one message so they run concurrently.
      
      ## Filling it in
      
      | Placeholder | Value |
      |---|---|
      | `{DOMAIN}` | the field, e.g. "medical AI", "interventional radiology" |
      | `{TEXT_DIR}` | the extracted-text cache from `scripts/extract_pdfs.py` |
      | `{LIT_DIR}` | `<vault>/Literature/` or the vault's existing equivalent |
      | `{ASSIGNMENTS}` | this agent's table of text file → destination note filename |
      | `{EXISTING_CONCEPTS}` | concept notes already in the vault, so links point somewhere real |
      
      ## Prompt
      
      ```
      You are writing Obsidian literature notes for {DOMAIN} papers. Each note is written from a
      text file extracted from the source PDF, which you read with the Read tool.
      
      INPUT   {TEXT_DIR}   (one .txt per paper, first 12 pages)
      OUTPUT  {LIT_DIR}    (one new .md per paper, created with the Write tool)
      
      Assigned papers:
      {ASSIGNMENTS}
      
      Concept notes that already exist — link to these by exact name, and propose new ones only
      when a paper genuinely introduces something absent from this list:
      {EXISTING_CONCEPTS}
      
      For each paper:
      
      1. Read the whole text file.
      
      2. Take from the text, and only from the text: the exact title including any subtitle; up to
         five authors as written; the journal or arXiv id; the publication date as YYYY-MM-DD; the
         design, results, comparisons, and stated limitations.
      
         Numbers, authors, and dates that are not in the text file do not go in the note. Do not
         supply them from memory, even for a paper you recognise. If the text does not state
         something, write "not stated in the extracted text" rather than filling the gap.
      
      3. Write the note to {LIT_DIR} using the template below. The PDF embed link must reproduce
         the source filename exactly — take the .txt filename and change the extension to .pdf,
         character for character, preserving case, spaces, and punctuation.
      
      4. If a note of that name already exists, skip it and report it. Do not overwrite.
      
      Template — follow it exactly, including frontmatter field names:
      
      ---
      title: "exact title from the text"
      authors: [Family1, Family2]
      journal: "journal or arXiv id"
      date_published: YYYY-MM-DD
      tags:
        - 📝Paper
        - 🤖AI/LLM
        - {domain tag}
      status: 🟢Completed
      aliases:
        - ShortAlias
      ---
      
      # Paper title
      
      📎 **Open the PDF inside Obsidian**: ![[exact_source_filename.pdf]]
      
      ## 📌 One-line summary
      
      ## 🎯 Background and aim
      *
      *
      
      ## 🔑 Methods and results
      1. **Design**:
      2. **Main results** (figures exactly as the text gives them):
      3. **Comparison**:
      4. **Limitations**:
      
      ## 💡 My reading
      *
      *
      
      ---
      ## Related notes
      * [[existing concept note]]
      * [[proposed new concept]]
      
      Report back: notes written, notes skipped as existing, and any paper whose text file was too
      short or too garbled to write from.
      ```
      
      ## Why the text-file constraint is absolute
      
      A subagent handed a PDF path it cannot open does not stop and report the failure. It writes
      the note anyway, from whatever it knows about a paper with that name — and the output is
      fluent, correctly formatted, and wrong in the numbers. Sample counts, IQRs, author lists, and
      p-values have all been produced this way. The `.txt` indirection is the only reliable guard.
      
    • tag-vocabulary.md 2.2 KB
      # Tag Vocabulary
      
      Tags exist so the graph view and Dataview queries stay usable. They are a filtering surface,
      not a metadata dump. Three well-chosen tags beat ten exhaustive ones.
      
      Emoji prefixes keep Obsidian's tag panel scannable by group.
      
      ## Source type — always exactly one
      
      - `📝Paper` — peer-reviewed or preprint research paper
      - `📰Article` — blog post, news piece, whitepaper
      - `📘Guide` — tutorial, how-to, reference guide
      - `🧪TechReport` — model technical report or system card
      
      ## Note type
      
      - `🧠Concept` — atomic concept note
      - `💭Thought` — the reader's own argument, drawing on several concepts
      - `🗺️MOC` — map of content
      - `📚Reference` — glossary or lookup note
      
      ## Technology
      
      - `🤖AI/LLM` — general large-language-model work
      - `🤖AI/{ModelFamily}` — a specific family when the paper is about it (`🤖AI/Claude`,
        `🤖AI/Gemini`, `🤖AI/Llama`, `🤖AI/DeepSeek`)
      
      ## Clinical domain
      
      - `🏥ClinicalReasoning` — diagnostic or management reasoning
      - `🏥ClinicalSimulation` — simulated clinical environments
      - `🏥ClinicalTrial` — randomized or controlled trials
      - `🏥ClinicalApplication` — real-world deployment studies
      - `🏥DifferentialDiagnosis` — differential-diagnosis focused
      
      ## Technical approach
      
      - `🧬RAG` — retrieval-augmented generation
      - `🤝MultiAgent` / `🤝Agent` — multi-agent or single-agent frameworks
      - `🔤Prompting` — prompt engineering
      - `🎓Training` — pre-training or post-training methods
      - `🧠Reasoning` — reasoning models and chain-of-thought work
      - `👁️Multimodal` — vision-language or audio
      
      ## Evaluation and safety
      
      - `📊Benchmark` — benchmark construction or results
      - `📊Evaluation` — evaluation methodology
      - `📊HeadToHead` — one system directly against another
      - `⚠️Safety` — safety-focused
      - `🛡️RedTeam` — adversarial testing
      - `⚖️Regulation` — regulatory frameworks
      
      ## Adding a tag
      
      Check first whether an existing tag covers it. If it genuinely does not, keep the
      emoji + PascalCase form (`📊NewConcept`). Avoid tags implied by the vault itself — `🏥Medicine`
      on every note in a medical vault filters nothing. Cap a note at four or five tags.
      
      Korean vaults using Korean tag names: `locale/ko/note_templates.md`.
      
    • templates.md 4.8 KB
      # Note Templates
      
      Two templates: literature notes (one per paper) and atomic concept notes (synthesized across
      papers). Match the frontmatter field names exactly — Dataview fails silently on a renamed
      field, returning an empty table rather than an error.
      
      Korean-structured vaults: see `locale/ko/note_templates.md`.
      
      ## 1. Literature note
      
      Save to `<vault>/Literature/{short descriptive title}.md`.
      
      ```markdown
      ---
      title: "Exact paper title, including any subtitle"
      authors: [Family1, Family2, Family3]   # max 5, then "et al."
      journal: "Journal name, or arXiv:XXXX.XXXXX"
      date_published: YYYY-MM-DD
      tags:
        - 📝Paper
        - 🤖AI/LLM
        - 🏥ClinicalReasoning
      status: 🟢Completed
      aliases:
        - ShortAlias
      ---
      
      # Paper title
      
      📎 **Open the PDF inside Obsidian**: ![[exact_source_filename.pdf]]
      
      ## 📌 One-line summary
      Who did what, how, and how much — one sentence, from the text.
      
      ## 🎯 Background and aim
      * What earlier work left unresolved
      * The problem this paper attacks
      * The hypothesis, if stated
      
      ## 🔑 Methods and results
      1. **Design**: n, dataset, evaluation protocol — as written in the text
      2. **Main results**: exact figures only (e.g. "accuracy 91.1%", "p < 0.001",
         "median 10, IQR 9–10")
      3. **Comparison**: against baselines or competing models
      4. **Limitations**: the ones the authors state
      
      ## 💡 My reading
      * What this implies for my own work — the reader's judgement, not the authors' claims
      * Second implication
      
      ---
      ## Related notes
      * [[domain hub note]]
      * [[existing concept note]]
      * [[proposed new concept]]
      ```
      
      ### Rules
      
      1. **Field names are fixed**: `title`, `authors`, `journal`, `date_published`, `tags`,
         `status`, `aliases`.
      2. **`authors` is a YAML list** of at most five entries; append `et al.` beyond that.
      3. **`date_published` is `YYYY-MM-DD`.** Year-only sources use `YYYY-01-01` with a note in
         the body.
      4. **Tags carry emoji prefixes** — see `tag-vocabulary.md`.
      5. **`status: 🟢Completed`** only once the note is written from verified extracted text.
      6. **The PDF embed is mandatory** and goes directly under the H1, reproducing the source
         filename exactly.
      7. **Every number comes from the extracted text.** Never from model knowledge.
      8. **The related-notes section carries at least four wikilinks** — a domain hub, at least one
         cross-folder link, and the concept notes this paper touches. A note with no outbound links
         is an island, and islands are never revisited.
      
      ## 2. Atomic concept note
      
      Save to `<vault>/Concepts/{concept name}.md`.
      
      ```markdown
      ---
      title: "Concept name"
      type: concept
      tags:
        - 🧠Concept
        - (domain tag)
      aliases:
        - AlternativeName
      related_papers:
        - "[[literature note 1]]"
        - "[[literature note 2]]"
        - "[[literature note 3]]"
      status: 🌱Seedling      # 🌱Seedling | 🌿Growing | 🌳Mature
      ---
      
      # Concept name
      
      ## 📖 Definition, in my own words
      The reader's understanding, not the textbook phrasing and not a sentence copied from any
      paper. This section is the whole point of the layer.
      
      ## 🌐 Why it matters
      Why this concept earns attention in this domain — the reader's judgement.
      
      ## 📚 How different papers treat it
      - **[[Paper A]]**: its treatment, with a specific quoted claim
      - **[[Paper B]]**: a different angle or method
      - **[[Paper C]]**: a contrary or complementary position
      
      ## 🔗 Related concepts
      - [[another atomic concept]] — how they connect
      - [[a concept not yet written]] — related, still a stub
      
      ## ❓ Open questions
      - What remains unanswered about this concept
      - What a future paper would have to show
      
      ## 📝 Update log
      - YYYY-MM-DD: drafted from {N} papers
      ```
      
      ### Rules
      
      1. **`type: concept`** separates these from literature notes in every query.
      2. **Status lifecycle** — 🌱Seedling: drafted, ~3 papers. 🌿Growing: 5–10 papers, the reader
         has edited it. 🌳Mature: 10+ papers, the reader's own position is established.
      3. **The definition must be rewritten by the reader.** A concept note that is still entirely
         AI-drafted is a summary, not a second layer. Create it as 🌱Seedling and say so.
      4. **`related_papers` entries are quoted wikilinks**: `"[[note title]]"`.
      5. **Open questions are never left empty** — one or two minimum. They are the seed of the
         next layer.
      
      ## 3. Filename conventions
      
      **Literature notes** — 3–5 keyword concepts, space-separated:
      
      - ✅ `Clinical reasoning GenAI vs physicians.md`
      - ✅ `MAIRA-2 grounded radiology report.md`
      - ❌ `towards accurate differential diagnosis with LLM clinicopathological NEJM.md` (the PDF's full title)
      - ❌ `paper_001.md` (carries no meaning)
      
      **Concept notes** — the concept, with an English alias in parentheses when the field uses one:
      
      - ✅ `Sequential decision-making.md`
      - ✅ `Management reasoning.md`
      - ❌ `Decision making.md` (too general to synthesize)
      - ❌ `SDM.md` (an abbreviation alone)
      
    • workflow.md 4.3 KB
      # The Three-Layer Vault
      
      Read this when the user asks how the pieces fit together, or why the skill refuses to write
      certain notes.
      
      ## The layers
      
      ```
      ┌──────────────────────────────────────────────────────┐
      │  Layer 3 — Thought      Thoughts/                    │
      │  The reader's own questions and hypotheses            │
      │  USER-AUTHORED. This skill never writes here.         │
      ├──────────────────────────────────────────────────────┤
      │  Layer 2 — Atomic       Concepts/                    │
      │  Concepts synthesized across papers                   │
      │  SKILL DRAFTS, USER REWRITES.                         │
      ├──────────────────────────────────────────────────────┤
      │  Layer 1 — Capture      Literature/  +  PDFs/        │
      │  One templated note per paper, plus the sources       │
      │  SKILL GENERATES from extracted text.                 │
      └──────────────────────────────────────────────────────┘
      ```
      
      Links alone do not make a second brain — they give topology without meaning. What makes the
      vault usable is that captured knowledge, the reader's understanding of recurring ideas, and
      the reader's own open questions live in separate places and are maintained differently.
      
      Only layer 1 scales through automation. Layer 2 is a collaboration. Layer 3 is not the
      skill's to write.
      
      ## What this skill does at each layer
      
      **Layer 1 — automated.** Extract PDF text, write one templated note per paper, keep
      frontmatter consistent so Dataview resolves, embed the PDF for split-view reading, track
      progress in the queue file.
      
      **Layer 2 — drafted, then handed over.** Identify ideas recurring across 3+ notes, draft
      concept notes with the definition section explicitly marked as a placeholder, propose which
      literature notes should link to each, and say when enough papers have accumulated to extract
      more.
      
      **Layer 3 — untouched.** The skill may point out tensions between papers that look worth
      thinking about. It does not write thought notes. What is worth thinking about is the reader's
      call.
      
      ## Folder layout
      
      ```
      vault/
      ├── MOC.md                    # dashboard, usually Dataview-driven
      ├── Literature/               # layer 1 — one note per paper
      ├── Concepts/                 # layer 2 — atomic concepts
      ├── Thoughts/                 # layer 3 — user only
      └── PDFs/                     # the source files the notes embed
      ```
      
      Text extraction caches outside the vault (`~/.local/cache/paper-vault-texts/` by default) so
      intermediate files never sync to other devices.
      
      **Honor the layout that exists.** Vaults in the wild use `02_research/논문/`, `papers/`,
      `Reading/`, and many others. Match what is there and never rename a folder the user already
      organizes around. Korean-structured vaults: `locale/ko/note_templates.md`.
      
      ## End to end
      
      **First run** — confirm PyMuPDF; agree the vault paths; create the literature folder and the
      text cache; extract; build `PAPER_QUEUE.md` from the PDF list; run the first batch of five
      subagents.
      
      **Each subsequent batch** — extract any new PDFs, group the batch thematically, run five
      subagents, mark the queue, and report which concepts are approaching the 3-paper threshold.
      
      **Concept pass, every 10+ papers** — scan for recurring terms, filter against the criteria in
      `concept-extraction.md`, draft three to five notes, hand them to the user to rewrite the
      definitions.
      
      ## When the vault is working
      
      The user opens a note and reads the PDF beside it. Dataview tables populate. Concept notes
      carry three or more backlinks. The user has started writing in layer 3 unprompted.
      
      And the one that decides whether any of the rest matters: **the user trusts the notes enough
      to cite them.** That trust is broken by a single fabricated number, and it does not come
      back — which is why extraction to text, and never writing from model knowledge, is the rule
      the others are built around.
      
  • scripts
    • extract_pdfs.py 2.5 KB
      """
      Extract text from a folder of PDFs using PyMuPDF.
      
      Usage:
          python extract_pdfs.py <pdf_folder> <output_folder> [max_pages]
      
      Default max_pages: 12 (covers abstract + intro + methods + results + discussion
      for most research papers).
      
      Output: One .txt file per PDF in the output folder, with page breaks marked by
      '===PAGE BREAK==='.
      """
      
      import fitz  # PyMuPDF
      import sys
      import os
      
      
      def extract_pdf_pages(pdf_path, output_dir, max_pages=12):
          """Extract text from the first max_pages of a PDF to a .txt file."""
          if not os.path.exists(pdf_path):
              print(f"ERROR: PDF not found at {pdf_path}")
              return False
      
          filename = os.path.basename(pdf_path)
          base_name = os.path.splitext(filename)[0]
          out_path = os.path.join(output_dir, f"{base_name}.txt")
      
          try:
              doc = fitz.open(pdf_path)
              num_pages = min(len(doc), max_pages)
              texts = []
              for page_num in range(num_pages):
                  page = doc.load_page(page_num)
                  texts.append(page.get_text("text"))
      
              full_text = "\n\n===PAGE BREAK===\n\n".join(texts)
      
              with open(out_path, "w", encoding="utf-8") as f:
                  f.write(full_text)
      
              return True
          except Exception as e:
              print(f"FAILED {filename}: {e}")
              return False
      
      
      def extract_folder(pdf_folder, output_folder, max_pages=12):
          """Extract text from all PDFs in a folder."""
          os.makedirs(output_folder, exist_ok=True)
          count = 0
          failed = 0
      
          for filename in os.listdir(pdf_folder):
              if filename.lower().endswith(".pdf"):
                  pdf_path = os.path.join(pdf_folder, filename)
                  if extract_pdf_pages(pdf_path, output_folder, max_pages):
                      count += 1
                  else:
                      failed += 1
      
          print(f"Extracted {count} PDFs (up to {max_pages} pages each)")
          if failed:
              print(f"Failed: {failed}")
          return count, failed
      
      
      if __name__ == "__main__":
          if len(sys.argv) < 3:
              print("Usage: python extract_pdfs.py <pdf_folder> <output_folder> [max_pages]")
              sys.exit(1)
      
          pdf_folder = sys.argv[1]
          output_folder = sys.argv[2]
          max_pages = int(sys.argv[3]) if len(sys.argv) > 3 else 12
      
          if os.path.isdir(pdf_folder):
              extract_folder(pdf_folder, output_folder, max_pages)
          elif os.path.isfile(pdf_folder):
              # Single PDF
              os.makedirs(output_folder, exist_ok=True)
              extract_pdf_pages(pdf_folder, output_folder, max_pages)
          else:
              print(f"ERROR: {pdf_folder} is not a file or directory")
              sys.exit(1)
      
  • SKILL.md 7.8 KB
    ---
    name: obsidian-paper-vault
    description: Turn a folder of research PDFs into an Obsidian knowledge vault — consistently formatted literature notes with frontmatter, PDF embed links, and cross-referenced atomic concept notes. Use whenever the user wants PDFs converted to Obsidian notes, a batch of papers summarized into a common template, a research "second brain" built or extended, or concepts extracted across accumulated notes — even if they never say "Obsidian". Pairs with /lit-sync, which owns the same vault folders from the Zotero/BibTeX side.
    triggers: obsidian-paper-vault, paper vault, second brain, PDF를 Obsidian 노트로, 논문 요약 노트, 논문 노트 만들어줘, 이 폴더의 PDF 정리해줘, batch process papers, add papers to vault, extract concepts from papers, literature vault
    tools: Read, Write, Edit, Bash, Grep, Glob
    model: inherit
    ---
    
    # Obsidian Paper Vault
    
    Converts a folder of research PDFs into a two-layer Obsidian vault: **literature notes**
    (one per paper, templated) and **atomic concept notes** (synthesized across papers).
    
    The rules below are not style preferences. Each one is here because its absence produced a
    specific, silent failure — a fabricated patient count, a broken PDF link, an empty Dataview
    table — in a vault of 100+ papers.
    
    ## Relationship to /lit-sync
    
    Both skills write literature and concept notes into the same vault folders. They enter from
    opposite ends and must not overwrite each other.
    
    | | `/lit-sync` | `obsidian-paper-vault` |
    |---|---|---|
    | Input | Zotero collection / `refs.bib` | a folder of PDFs |
    | Note key | citekey | short descriptive title |
    | Owns | `manuscript/_src/refs.bib` | extracted-text cache |
    
    **Never overwrite an existing note.** If a note for the paper already exists (by title, DOI,
    or citekey), report it and skip. When both skills are in play, `/lit-sync` notes are the
    bibliographic spine; this skill's notes are the read-through summaries.
    
    ## Step 0: Resolve the vault layout — ask, do not assume
    
    Establish three paths before writing anything:
    
    1. **Vault root** — from the user, or `$OBSIDIAN_VAULT`. Never guess a home-directory path.
    2. **Literature notes folder** — default `Literature/`. If the vault already has a folder
       serving this role (`02_research/논문/`, `Papers/`, `文献/`), **honor the existing layout**
       rather than imposing the default.
    3. **Concept notes folder** — default `Concepts/`, same honor-what-exists rule.
    
    For a vault whose structure is Korean, see `references/locale/ko/note_templates.md` — folder
    names and note headings in Korean, opt-in.
    
    Also confirm PyMuPDF is available: `python3 -c "import fitz; print(fitz.__version__)"`
    (install with `pip install PyMuPDF`). Text extraction caches to
    `~/.local/cache/paper-vault-texts/` unless the user names another location.
    
    ## Step 1: Pre-extract PDF text — always, for any batch
    
    ```bash
    python3 scripts/extract_pdfs.py <pdf_folder> <text_cache_folder> [max_pages]
    ```
    
    Defaults to 12 pages, which covers abstract through discussion for most papers.
    
    **Never hand a PDF path to a subagent.** A subagent that cannot open a file does not report
    failure — it writes the note from training data, and the result is a plausible note with
    invented numbers. Pass the `.txt` paths instead. Single-paper interactive work may read the
    PDF directly (the Read tool handles PDFs); batches may not.
    
    ## Step 2: Launch subagents in parallel
    
    Five subagents × 5–6 papers is the working batch size: enough parallelism to clear 25 papers
    in one pass, small enough that per-agent quality holds. Group papers thematically per agent
    so each one can spot recurring concepts.
    
    Give each subagent: its assigned text-file paths with destination filenames, the template
    from `references/templates.md` verbatim, the list of concept notes that already exist, and
    the prohibition on inventing anything. `references/subagent-prompt.md` holds the full prompt.
    
    ## Step 3: Track progress in a queue file
    
    Keep `PAPER_QUEUE.md` in the vault with per-paper status (done / pending / skipped / in
    progress) so a 200-paper vault survives across sessions. Update it after each batch.
    
    ## Step 4: Extract concept notes once 10+ literature notes exist
    
    A phrase earns a concept note when it appears in 3+ notes, carries pedagogical value, and is
    treated differently by different papers. Model names, datasets, and journals are entities,
    not concepts. See `references/concept-extraction.md` for the full criteria, the frequency
    scan, and the seedling/growing/mature lifecycle.
    
    Roughly one new concept note per 5–7 literature notes is healthy. Faster than that is concept
    inflation, and it shows up as dozens of stub notes the user never edits.
    
    ## Anti-Hallucination rules (non-negotiable)
    
    A note that is fluent, correctly formatted, and wrong in its numbers is worse than no note:
    the user cites it. These three rules exist to make that failure impossible rather than
    unlikely.
    
    1. **Numbers, authors, and dates come from the extracted text only** — never from model
       knowledge, however familiar the paper. Well-known papers drift between versions, and that
       is exactly where invented values look most plausible.
    2. **Subagents receive `.txt` paths, never PDF paths.** A subagent that cannot open a file
       does not report the failure; it writes from training data. The text indirection is the
       only reliable guard.
    3. **What the text does not state, the note does not claim.** Write "not stated in the
       extracted text" instead of filling the gap.
    
    **Gate — before a batch is accepted**: spot-check two notes against their text files (one
    sample size, one effect estimate). If either value is absent from the text, stop the batch
    and report it rather than continuing. This gate is the user's call to waive, not the skill's.
    
    ## Structural rules
    
    4. **Preserve the PDF filename exactly** in `![[filename.pdf]]`. Obsidian embeds are
       sensitive to case, spaces, and punctuation — take the text filename and swap `.txt` for
       `.pdf`, character for character.
    5. **Match the frontmatter field names** in `references/templates.md`. Dataview queries break
       on a renamed field, and they break by returning an empty table, not an error.
    6. **Use the existing tag vocabulary** (`references/tag-vocabulary.md`) rather than inventing
       top-level tags.
    7. **Name notes with 3–5 keyword concepts**, not the PDF's full title and not `paper_001`.
    8. **Never overwrite an existing note** — see the `/lit-sync` boundary above.
    
    **Gate — before concept notes are presented as done**: concept notes ship as 🌱Seedling with
    the definition marked as a placeholder, and require user review before they count as the
    reader's own. Say so explicitly when handing them over.
    
    ## Reference files
    
    | File | Read it when |
    |---|---|
    | `references/templates.md` | writing any literature or concept note |
    | `references/subagent-prompt.md` | launching a batch |
    | `references/concept-extraction.md` | extracting concepts across notes |
    | `references/tag-vocabulary.md` | choosing tags |
    | `references/workflow.md` | the user asks how the layers fit together |
    | `references/locale/ko/note_templates.md` | the vault is Korean-structured |
    | `assets/example_paper_note.md` | unsure about literature-note formatting |
    | `assets/example_concept_note.md` | unsure about concept-note formatting |
    
    ## Troubleshooting
    
    | Symptom | Cause | Fix |
    |---|---|---|
    | Subagent says it could not read the PDF | it was given a PDF path | run `extract_pdfs.py`, pass `.txt` paths |
    | Note reads plausibly but numbers are wrong | subagent wrote from training data | re-run against the text file; verify n, CI, p-values |
    | Dataview table is empty | frontmatter field renamed | match `references/templates.md` exactly |
    | PDF embed shows a broken tile | filename mismatch | compare character by character, including case |
    | Note content is generic | text file is abstract-only or OCR is poor | re-extract with more pages, or check the source PDF |
    
  • skill.yml 2.6 KB
    schema_version: 2
    name: obsidian-paper-vault
    layer: A
    owner_domain: pdf_to_vault_notes
    maturity: official
    when_to_use:
      - User has a folder of research PDFs and wants Obsidian literature notes
      - Batch-summarizing papers into one consistent template
      - Building or extending a research "second brain" vault
      - Extracting atomic concept notes once enough literature notes have accumulated
    when_NOT_to_use:
      - Notes should come from a Zotero collection or refs.bib (use /lit-sync)
      - Literature search without note-building (use /search-lit)
      - Downloading open-access full texts (use /fulltext-retrieval)
      - Verifying citations in a manuscript (use /verify-refs)
    inputs:
      - a folder of PDF files
      - vault root + literature/concept folder names (asked, never assumed)
    outputs:
      - obsidian_literature_notes
      - obsidian_concept_notes
      - PAPER_QUEUE.md  # resumable batch progress
    deterministic_scripts:
      - scripts/extract_pdfs.py  # PyMuPDF text pre-extraction; batch notes are written from .txt, never from PDFs
    side_effects:
      - may_write_obsidian_notes
      - writes_text_cache  # ~/.local/cache/paper-vault-texts/ by default
    downstream_consumers:
      - lit-sync  # concept-note extraction over the same vault folders
    ssot_boundary:
      - Never overwrites an existing note. /lit-sync is the sole writer of manuscript/_src/refs.bib and of citekey-named literature notes; this skill writes title-named notes from PDFs.
    quality_gates:
      - text_first: batch notes are written from extracted .txt files, never from PDF paths handed to subagents
      - filename_fidelity: every PDF embed link reproduces the source filename character for character
      - frontmatter_contract: field names match references/templates.md so Dataview queries resolve
    forbidden_actions:
      - fabricate_numbers_authors_or_dates
      - pass_pdf_paths_to_subagents
      - overwrite_existing_notes
      - invent_top_level_tags
    
    # v2.1 quality card
    purpose: "Convert a folder of research PDFs into templated Obsidian literature notes plus atomic concept notes synthesized across them."
    safety_boundaries:
      - "Every number, author, and date is transcribed from extracted PDF text; nothing is written from model knowledge."
      - "Existing notes are never overwritten."
    known_limitations:
      - "Requires PyMuPDF; scanned PDFs with poor OCR yield thin notes."
      - "Default extraction is the first 12 pages, so appendix-only content is missed unless max_pages is raised."
      - "Effects land in the user's Obsidian vault, so there is no self-contained demo."
    validation_commands:
      - "python3 scripts/extract_pdfs.py <pdf_folder> <cache_folder>"
      - "grep -c 'date_published' <vault>/<literature_folder>/*.md"
    evidence_surface: manual_workflow
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related