agentleFS
WenyuChiouWenyuChiou/research-hub/skills/paper-summarize/SKILL.md

paper-summarize

Skill67 starsChanged 7 months agoMITView on GitHub

After research-hub ingests a cluster of cited papers, fill the per-paper Key Findings + Methodology + Relevance sections in BOTH Obsidian markdown and the Zotero child note. Use when the user says \"fill the TODO Key Findings/Methodology blocks left by research-hub auto\", \"I just ran auto and don't know what these papers are about\", or \"summarize the papers in cluster X\". Invokes a supported LLM CLI on each paper's abstract. NOT for summarizing the user's own manuscript draft — that's `paper-memory-builder`. NOT for cluster-level briefs — that's `research-hub notebooklm generate`. This skill is per-cited-paper only. If the user says \"extract claims from these papers\", disambiguate before acting: their own manuscript draft → `paper-memory-builder`; a cross-paper comparison matrix → `literature-triage-matrix`; per-cited-paper Key Findings → this skill.

The file

We split this skill into the rules it gives an agent

3 rules. About 0 are common, 0 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Only an explicitly owned Hub summary note is updated with <h1>Summary + Abstract + Key Findings <ul> + Methodology + Relevance.

    line 47
  2. Very specific:

    If no owned summary exists, a tagged summary is created.

    line 48
  3. Very specific:

    After applying, scan raw/<cluster>/*.md — every paper's ## Key Findings callout should have real bullets instead of [TODO].

    line 101

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

paper-summarize

The auto pipeline ingests metadata + abstract only — Summary / Key Findings / Methodology / Relevance stay as [TODO] skeletons in both Obsidian and Zotero. Cluster-level summarization (NotebookLM brief, crystals) does NOT fill per-paper notes. So after auto, the user has nothing scannable per paper without opening the PDF.

This skill fills that gap. One LLM call per paper produces JSON-validated content for both destinations. These writes are not a distributed transaction: unconfirmed remote writes remain unknown, and local compensation is best-effort, never proof that the destinations are synchronized.

When to use

Trigger phrases:

  • "Summarize the papers in cluster X."
  • "Fill the TODO Key Findings for X."
  • "I just ran auto X and the notes are empty — give me real summaries."
  • "Update Zotero notes for cluster X with what each paper actually says."

Not for:

  • Generating a single CLUSTER-LEVEL summary — that's research-hub notebooklm generate (NotebookLM brief).
  • Filling Q&A on the cluster — that's research-hub crystal emit/apply.
  • Reading PDFs — abstract-only by design. PDF parsing is out of scope; the LLM is told to mark "[PDF needed]" if abstract is too thin.
  • Verifying brief vs source — that's notebooklm-brief-verifier.

Inputs

  • Cluster slug (must already exist in the vault under raw/<slug>/)
  • Optional LLM CLI override (claude, codex, gemini, opencode, aichat, cursor, or configured custom adapter)
  • Optional --apply flag (default off, dry-run)

The skill reads each paper's frontmatter (DOI, year, zotero-key) + the ## Abstract body block. Papers with empty abstract get a "PDF needed" marker rather than hallucinated findings.

Outputs

For each paper, three sections are rewritten:

  1. Obsidian markdown at raw/<cluster>/<paper-slug>.md:
    • ## Key Findings callout block (3–5 bullets)
    • ## Methodology callout block (one sentence)
    • ## Relevance callout block (1–2 sentences linking to the cluster topic)
    • Anchor IDs (^findings, ^methodology, ^relevance) preserved.
  2. Zotero child note for the paper's parent item (looked up via zotero-key frontmatter):
    • Only an explicitly owned Hub summary note is updated with <h1>Summary + Abstract + Key Findings <ul> + Methodology + Relevance. Unmarked notes are preserved.
    • If no owned summary exists, a tagged summary is created; ambiguous ownership is refused. See docs/zotero-summary-note-ownership.md for preservation and unknown-outcome limits.

Both writes must be confirmed for a paper to count as "applied". If the remote outcome is unconfirmed, report it as unknown and do not retry automatically. Local compensation restores the original note only if its current text still matches this invocation's written text; a newer observed edit is preserved. Failed compensation is reported for reconciliation rather than hiding other papers' outcomes. This check does not exclude a concurrent writer racing after the check. Inspect both destinations before an explicit retry; success counters count confirmed applied papers, not proof that failed/unknown papers were untouched.

Failure modes

  • No LLM CLI on PATH: prompt is saved to <vault>/.research_hub/artifacts/<cluster>/summarize-prompt.md. This is prompt-only success (exit code 0; ok=True): no summaries were generated or applied, even with --apply. Re-running --apply does not import externally generated summaries. If the native host agent has available, authorized tools, it can read this prompt and return readable abstract-based summaries. These are not full-text validation. Persisting them requires a selected, separately authorized supported destination operation. The apply_cluster_summaries MCP tool defaults to writing both Obsidian and Zotero; it is not an automatically authorized fallback. If a supported authorized persistence route is unavailable, preserve the readable result and clearly report saving as pending; do not ask the researcher to author JSON.
  • LLM returns malformed JSON: report is ok=False with error="LLM response had no parseable JSON object". No writes.
  • Paper slug in payload not in cluster: that entry is skipped with reason logged; other entries still applied.
  • Empty key_findings / methodology / relevance: entry skipped.
  • Zotero write is unconfirmed for one paper: report unknown, do not retry automatically, and attempt guarded local compensation. A newer observed edit or compensation failure is preserved/reported; other papers retain their own outcomes.

Verification

This skill's contract is exercised end-to-end by the test suite. The suites stub the LLM CLI but execute real Obsidian markdown writes against a fixture vault and real Zotero child-note writes against a mocked Zotero adapter. Successful rollback, unavailable compensation, newer observed edits, and unknown remote acknowledgement are distinct contracts; the bounded direct fault script adds coverage without claiming live-provider acceptance.

# Run the full paper-summarize suite (23 tests)
python -m pytest -q \
  tests/test_v069_summarize.py \
  tests/test_v073_parallel_summarize.py \
  tests/test_v080_resummarize.py

Coverage breakdown:

Test fileCountWhat it covers
tests/test_v069_summarize.py17Prompt builder shape, validator (rejects unknown slugs / empty fields / wrong types), Obsidian + Zotero apply path, rollback when Zotero fails, no-LLM-on-PATH fallback
tests/test_v073_parallel_summarize.py3Parallel summarize across multiple clusters, ordering, error isolation
tests/test_v080_resummarize.py3Re-summarize behaviour: idempotent on same input, overwrite on different LLM output, --no-zotero path

For a manual smoke check against a live vault:

# Dry-run (emit prompt + show LLM output, no writes)
research-hub summarize --cluster <slug>

# Live run (writes to Obsidian + Zotero)
research-hub summarize --cluster <slug> --apply

# Override LLM
research-hub summarize --cluster <slug> --llm-cli codex --apply

# Obsidian-only (skip Zotero — useful when Zotero is offline)
research-hub summarize --cluster <slug> --apply --no-zotero

After applying, scan raw/<cluster>/*.md — every paper's ## Key Findings callout should have real bullets instead of [TODO].

Operating notes

  • Findings-first: the prompt instructs the LLM to state the result, not "The paper shows that…".
  • Anchored to the abstract: every Key Finding must trace to something the abstract claims. The LLM is told to mark uncertain claims with [likely].
  • Re-running may regenerate different content and overwrite the selected summary sections; this is not an idempotency or duplicate-prevention guarantee. --no-zotero and --no-obsidian disable only their named destination: they are not preview flags, and --apply still writes to the other enabled destination. Omit --apply to avoid summary destination writes; model invocation and local prompt artifacts may still occur.
  • Each paper has separate destination outcomes with best-effort local compensation, not an atomic cross-system transaction. Preserve unknown outcomes and reconcile the exact intended write before any explicit retry.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.