skills/paper-cluster-by-theme/SKILL.md
Groups a set of kept papers into 2-5 thematic clusters before synthesis, using abstract semantics + matched-keyword overlap. Names each cluster with a short noun phrase that describes what the cluster argues, not just the topic. Surfaces an "outliers" bucket for single-paper themes that don't fit. Domain-neutral - usable for any literature-scan workflow. Use after relevance filtering and before writing the synthesis report. Trigger keywords - cluster papers, group by theme, thematic clusters, paper themes, organize papers.
npx skillsauth add lyndonkl/claude paper-cluster-by-themeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Take a list of relevance-filtered papers and produce thematic clusters that the synthesis layer can write about rather than list.
A "cluster" here is not a topic label — it's an argument. "Diffusion models for protein design" is a topic. "Diffusion models are converging on AlphaFold-comparable accuracy without MSAs" is a theme. The synthesis is much stronger when clusters describe what the papers collectively argue.
- [ ] Step 1: Read all kept papers' titles, abstracts, and matched keywords
- [ ] Step 2: Identify 2-5 candidate themes from the abstract content
- [ ] Step 3: Assign each paper to its best-fit theme (or to outliers)
- [ ] Step 4: Re-name each theme as an argument-shaped phrase
- [ ] Step 5: Validate clusters (no empty cluster, no over-stuffed cluster, no paper in two)
- [ ] Step 6: Return clusters + outliers + assignment rationale
Step 1 — Read inputs
The skill takes a list of records (the KEEP set from paper-relevance-filter). It needs id, title, abstract, and matched_keywords for each.
Step 2 — Candidate themes
Two signals to use, in order:
Aim for 2-5 clusters. Hard cap at 5 — beyond that, the synthesis layer cannot say anything coherent about each. If you have only 2-3 papers total and they don't form a theme, return one cluster called "Notable single papers" — do not force 3 clusters of 1.
Step 3 — Assign papers
Each paper goes to exactly one cluster (or outliers). When a paper plausibly fits two, choose the cluster where the paper's contribution (read from the abstract's last 1-2 sentences) is the better fit — not just where its keywords match. Note the alternative in also_fits.
Outliers: a paper with no good cluster fit. Do not exceed 3-4 outliers; if you have more, your clustering is too narrow — go back to Step 2 and split a cluster.
Step 4 — Argument-shaped names
Bad cluster names:
Good cluster names (argument-shaped):
A good name is a one-line argument the cluster collectively makes. If you can't write that argument because the papers in the cluster disagree, that's actually fine — name it as a tension: "Disagreement on whether X requires Y."
Step 5 — Validate
Reject and redo if:
Step 6 — Return
{
"clusters": [
{
"name": "Protein design moves from sequence-only to sequence+structure conditioning",
"rationale": "Three of the kept papers (P1, P2, P5) all argue that adding structural context at training time outperforms sequence-only baselines. P5 disagrees on the magnitude.",
"papers": ["10.1101/2026.05.07.123456", "PMID:39000001", "10.1101/2026.05.06.654321"],
"tension": "P5 reports smaller gains than P1; worth noting in synthesis."
},
{
"name": "Single-cell foundation models start releasing benchmarks, not just weights",
"rationale": "Two papers (P3, P7) release benchmark suites alongside the model.",
"papers": ["PMID:39000002", "10.1101/2026.05.05.111111"],
"tension": null
}
],
"outliers": [
{
"id": "PMID:39111222",
"rationale": "Single paper on cryo-EM segmentation; doesn't fit either cluster but matches watchlist."
}
],
"summary": {
"input_papers": 17,
"cluster_count": 3,
"outlier_count": 2,
"largest_cluster_size": 6,
"smallest_cluster_size": 3
}
}
Pattern A — Focused watchlist, week with 5-15 papers: typically 2-3 strong clusters + 1-2 outliers. The default.
Pattern B — Broad watchlist, week with 20+ papers: 4-5 clusters; cluster names get more specific (one keyword's worth each). Risk: cluster names become topic labels rather than arguments. Push back on yourself.
Pattern C — Thin week (3-5 kept papers): skip clustering. Return one cluster "Notable single papers" with all of them. The synthesis layer will write per-paper rather than per-theme.
Pattern D — Disagreement-heavy week: when 2+ papers in a cluster directly contradict each other on a finding, name the cluster as the tension and call this out in tension. The synthesis layer treats this as a high-value 30K-ft observation.
also_fits as a note, not as a duplicate assignment.rationale field that names which papers anchor the theme and how. Without it the synthesis writer has to re-derive your reasoning.| Cluster count | When | | ------------- | -------------------------------------------------- | | 1 | Thin week (≤ 5 papers, no real grouping) | | 2-3 | Default for focused weekly digest | | 4-5 | Broad watchlist or unusually busy week | | 6+ | Reject — merge until ≤ 5 |
| Naming test | Pass? | | ---------------------------------------------------------------- | ----- | | Is the name a noun phrase that could be a topic in a textbook? | FAIL | | Does the name name an argument or a tension? | PASS | | Could a reader predict the cluster's content from the name? | PASS | | Could you swap two clusters' names and have it still make sense? | FAIL — names are too generic |
testing
--- name: advisory-edit description: A strict advisory-only editing discipline for a writer who dictates ("speaks out") essays and wants help WITHOUT having their voice changed. The editor directs structure, flags grammar, and suggests strategic language — but never modifies the writer's text unless the writer explicitly says "apply" / "make that change" / "rewrite this." Produces a line-referenced, suggestion-only critique where every item is marked the writer's call. Four passes: structural, l
testing
Provides the house style for analyst-grade strategist writing — third-person register with sparing first-person, no em dashes, no "not X, not Y, not Z" negation cascades, numbered footnote citations rather than inline source parentheticals, specific opinion-signaling phrases, and topic-forward paragraph structure modeled on voice patterns observed in Damodaran's Musings on Markets and Thompson's Stratechery. Use when consolidating working notes into a finished long-form strategist or analyst report that must read as written by a senior human analyst rather than an AI assistant.
testing
Renders a markdown report to a PDF using pandoc with xelatex (11pt serif body, 1-inch margins, numbered footnotes, formal heading hierarchy). Requires a one-time install of pandoc and a LaTeX engine on the user's machine — basictex on macOS or texlive-xetex on Linux. Does not attempt automatic install. Fails loudly with the exact install commands if pandoc or xelatex is missing on the user's PATH. Use when producing a finished strategist or analyst report PDF from a polished markdown source.
testing
Produces step-by-step computational walkthroughs of vector and matrix operations as a sequence of numbered "frames", showing the explicit state at each step. The text-equivalent of a 3Blue1Brown animation — each frame shows what changed and why, so the learner can re-trace the operation by hand. Use when the learner needs to *see* a computation unfold (eigenvalue computation, attention with 3 tokens, gradient descent step, SVD on a 2×2, layer norm on a 3-vector, softmax of a small input), when an explanation has been given but the learner needs to ground it in a worked example, or when introducing an operation that's intimidating in symbol form but trivial in pencil-and-paper form.