paper-cluster-by-theme
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.
What this skill does
# paper-cluster-by-theme
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*.
## Workflow
```
- [ ] 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:
1. **Matched-keyword groupings** (cheap, mechanical): if half the kept papers all share one keyword, that's a strong candidate cluster. Group by the most common matched keyword first; this gets you 70% of the way for a focused watchlist.
2. **Abstract semantics** (qualitative): for papers grouped by the same keyword but doing different *kinds* of work (e.g., review vs benchmark vs new method), split into sub-clusters. Conversely, for papers in different keyword groups that read like the same argument (e.g., a methods paper and an application paper extending it), merge.
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:
- "Protein design"
- "Single-cell papers"
- "AI in biology"
Good cluster names (argument-shaped):
- "Protein design moves from sequence-only to sequence+structure conditioning"
- "Single-cell methods converge on multi-modal embeddings as default"
- "AI-discovered targets are being re-validated with classical biology"
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:
- Any cluster has 0 papers (delete it)
- Any cluster has > 70% of papers (split it)
- Any paper appears in two clusters (force-pick one)
- Total clusters > 5 (merge nearest two)
- Outliers > 4 (split a cluster to absorb)
**Step 6 — Return**
```json
{
"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
}
}
```
## Common Patterns
**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.
## Guardrails
1. **Never name a cluster after a topic when you can name it after an argument.** Topic names tell the user what the papers are about; argument names tell them what to take away. The latter is the whole point of the digest.
2. **Never put a paper in two clusters.** If it fits two, the second one goes in `also_fits` as a note, not as a duplicate assignment.
3. **Never exceed 5 clusters.** The synthesis layer renders one paragraph per cluster; 6+ is unreadable.
4. **Never coerce 3 clusters when there are clearly 2.** A real "1 cluster + 4 outliers" week is honest. A faked "3 clusters of 1-2 papers each" is noise.
5. **Never cluster by source.** "All the bioRxiv papers" is not a theme. Source belongs in the per-paper line, not the cluster name.
6. **Never cluster by date within the week.** Same reason — temporal proximity is not a theme.
7. **Always cite the rationale.** Each cluster has a `rationale` field that names which papers anchor the theme and how. Without it the synthesis writer has to re-derive your reasoning.
## Quick Reference
| 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 |
Related in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.