From eaa12c8c756352811e02b5724694f46a215d18dd Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Sat, 2 May 2026 11:02:12 +0800 Subject: [PATCH] Align skills with the Agent Skills specification Replace the {{*SKILL_DIR}} placeholder convention with spec-compliant relative paths from each skill root, drop the now-redundant "Path Resolution Protocol" boilerplate sections, switch python invocations to python3 for portability, and add license + compatibility frontmatter recognized by the spec. CLAUDE.md gains a pointer to the official spec and best-practice guides. Tests updated to enforce the new convention. Co-Authored-By: Claude Opus 4.7 --- CLAUDE.md | 7 +- skills/analyze-paper/SKILL.md | 20 +--- skills/brainstorm/SKILL.md | 19 +--- skills/clarify-goal/SKILL.md | 1 + skills/critique/SKILL.md | 16 +-- skills/formalize-problem/SKILL.md | 25 ++--- skills/investigate/SKILL.md | 24 ++--- skills/reaper/SKILL.md | 2 + skills/reaper/references/search-tools.md | 30 ++---- skills/review-literature/SKILL.md | 2 + skills/search-paper/SKILL.md | 54 ++++------ skills/search-paper/arxiv.py | 8 +- skills/search-paper/dblp.py | 2 +- skills/search-paper/iacr.py | 10 +- skills/search-paper/openalex.py | 2 +- skills/search-paper/semantic_scholar.py | 6 +- skills/synthesize/SKILL.md | 1 + tests/test_skills_structure.py | 125 ++++++++--------------- 18 files changed, 127 insertions(+), 227 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 321f711..4cc3268 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -27,7 +27,12 @@ pip install arxiv requests beautifulsoup4 ## Key conventions -- Skills are the unit of composition. Each skill directory contains a `SKILL.md` with YAML frontmatter — `name` (lowercase + hyphens, matches the directory name) and `description` are required by the [`vercel-labs/skills`](https://github.com/vercel-labs/skills) parser; everything else is optional. +- Skills follow the [Agent Skills specification](https://agentskills.io/specification). Each skill directory contains a `SKILL.md` with YAML frontmatter. Required fields: `name` (1–64 chars, lowercase alphanumeric + hyphens, no leading/trailing/consecutive hyphens, must match the parent directory name) and `description` (1–1024 chars, describes both what the skill does and when to use it). Recognized optional fields: `license`, `compatibility`, `metadata`, `allowed-tools`. All skills in this repo set `license: Apache-2.0`. +- Skill authoring follows the [best practices](https://agentskills.io/skill-creation/best-practices) and [description guidance](https://agentskills.io/skill-creation/optimizing-descriptions): + - Keep `SKILL.md` under 500 lines / ~5000 tokens; use `references/` for detail loaded on demand, and tell the agent *when* to load each reference file. + - Spend context wisely: add what the agent lacks, omit what it knows. Provide a clear default rather than a menu of options. + - Match instruction specificity to task fragility — be prescriptive for fragile/destructive operations, descriptive (with the *why*) for flexible ones. + - Descriptions use imperative phrasing ("Use when…"), focus on user intent, and stay under 1024 chars. - The orchestrator skill (`/reaper`) runs the full pipeline: clarify → analyze → literature → formalize → brainstorm → investigate ↔ critique → synthesize. After delivery, users can iterate by re-invoking the `/critique` skill with feedback. - Runtime state goes in `reaper-workspace/` (gitignored). Never commit workspace artifacts. - The six methodology principles (separation of concerns, fixed evaluation signal, structured results log, keep-or-discard loop, never stop, clarity and simplicity) govern how skills behave. diff --git a/skills/analyze-paper/SKILL.md b/skills/analyze-paper/SKILL.md index dfc49f1..86434e2 100644 --- a/skills/analyze-paper/SKILL.md +++ b/skills/analyze-paper/SKILL.md @@ -3,6 +3,8 @@ name: analyze-paper description: "Extract structured information from a research paper: system model, theorem statements, proof techniques, complexity claims, and red flags. Use when asked to analyze, summarize, or review an academic paper." user-invocable: true argument-hint: " [--output ] [--goal \"\"]" +license: Apache-2.0 +compatibility: "Requires PDF reading capability for the paper under analysis." --- # Analyze Paper @@ -25,18 +27,6 @@ analyze-paper reaper-workspace/papers/2024-1234.pdf --goal "post-quantum thresho - `--output `: Write output to the given path instead of the default `reaper-workspace/notes/paper-summary.md`. - `--goal ""`: The research goal as additional context. When provided, the output includes a **Relevance** section assessing how the paper relates to this goal, and reading depth is calibrated by relevance (see Step 1). -## Path Resolution Protocol - -This skill references files in sibling skills. **`{{REAPER_SKILL_DIR}}`** below is a template placeholder — **you MUST substitute it with the absolute install path of the `/reaper` skill before reading, or the read will fail.** Common install locations: - -- `~/.claude/skills/reaper/` (Claude Code) -- `~/.cursor/skills/reaper/` (Cursor) -- `~/.agents/skills/reaper/` (Codex CLI, Cline, Gemini CLI, Copilot, OpenCode, Warp, Goose, Replit — universal target) -- `~/.continue/skills/reaper/` (Continue) -- `~/.windsurf/skills/reaper/` (Windsurf) -- `/skills/reaper/` (during repo development) - -**Sibling-skill dependency**: This skill assumes the full `/reaper` package was installed together (`npx skills add SebastianElvis/reaper`). Single-skill installs will fail to resolve sibling references. ## Instructions @@ -44,7 +34,7 @@ This skill references files in sibling skills. **`{{REAPER_SKILL_DIR}}`** below Read the paper at the provided path using your host's file-read primitive (works for PDFs and text files on hosts that support PDF reading; otherwise extract text first). -Follow the three-pass strategy from `{{REAPER_SKILL_DIR}}/references/paper-analysis.md`: +Follow the three-pass strategy from `../reaper/references/paper-analysis.md`: - **Pass 1 (skeleton)**: Abstract, introduction, conclusion, theorem statements. Identify the main claims. - **Pass 2 (construction)**: Protocol details, proof sketches, figures. Understand the key technical idea. @@ -76,7 +66,7 @@ Write the extracted information to `reaper-workspace/notes/paper-summary.md` (or What problem does this paper solve? Why does it matter? ## System Model -[Extract all model dimensions relevant to the paper's domain. Consult `{{REAPER_SKILL_DIR}}/references/model.md` for the domain-appropriate dimensions to extract. Every applicable dimension must have a concrete answer.] +[Extract all model dimensions relevant to the paper's domain. Consult `../reaper/references/model.md` for the domain-appropriate dimensions to extract. Every applicable dimension must have a concrete answer.] ## Construction Overview High-level protocol description. Key technical idea. Building blocks used. @@ -105,7 +95,7 @@ Overall proof approach. Key lemmas. Reduction chain. Where the corruption thresh Non-standard notation. Formal definitions referenced by the proofs. ## Red Flags -Any concerns identified during reading (see `{{REAPER_SKILL_DIR}}/references/paper-analysis.md` for common red flags). +Any concerns identified during reading (see `../reaper/references/paper-analysis.md` for common red flags). ## Relevance [Present ONLY when --goal is provided. Tag one or more: *problem definition*, *formalization*, *solution technique*, *negative result*, *literature/context*, *writing model*. One sentence per tag explaining how this paper relates to the research goal.] diff --git a/skills/brainstorm/SKILL.md b/skills/brainstorm/SKILL.md index 079974f..4edfda4 100644 --- a/skills/brainstorm/SKILL.md +++ b/skills/brainstorm/SKILL.md @@ -3,6 +3,7 @@ name: brainstorm description: "Generate, prioritize, and refine research ideas based on current investigation state. Use when the pipeline needs new or better hypotheses — after formalization, between investigation batches, or when all current ideas are resolved." user-invocable: true argument-hint: "[context-hint]" +license: Apache-2.0 --- # Brainstorm @@ -42,18 +43,6 @@ brainstorm "explore liveness under partial synchrony" - `reaper-workspace/papers/` — downloaded PDFs and per-paper notes - The optional context hint from the argument -## Path Resolution Protocol - -This skill references files in sibling skills. **`{{REAPER_SKILL_DIR}}`** below is a template placeholder — **you MUST substitute it with the absolute install path of the `/reaper` skill before reading, or the read will fail.** Common install locations: - -- `~/.claude/skills/reaper/` (Claude Code) -- `~/.cursor/skills/reaper/` (Cursor) -- `~/.agents/skills/reaper/` (Codex CLI, Cline, Gemini CLI, Copilot, OpenCode, Warp, Goose, Replit — universal target) -- `~/.continue/skills/reaper/` (Continue) -- `~/.windsurf/skills/reaper/` (Windsurf) -- `/skills/reaper/` (during repo development) - -**Sibling-skill dependency**: This skill assumes the full `/reaper` package was installed together (`npx skills add SebastianElvis/reaper`). Single-skill installs will fail to resolve sibling references. ## Process @@ -71,7 +60,7 @@ Apply these techniques systematically. Not all will produce ideas every time — #### Gap-Finding (Qian: Fill in the Blank) -Map the dimensions of existing work and find unexplored combinations. Consult `{{REAPER_SKILL_DIR}}/references/model.md` for the domain-appropriate gap-finding matrix dimensions. Which cells in this matrix are empty? Those are candidate hypotheses. +Map the dimensions of existing work and find unexplored combinations. Consult `../reaper/references/model.md` for the domain-appropriate gap-finding matrix dimensions. Which cells in this matrix are empty? Those are candidate hypotheses. #### Problem Inversion (Hamming) @@ -100,7 +89,7 @@ If a hypothesis has trended toward refutation over 3+ cycles (counterexample att ### 3. Screen Against Known Impossibilities -For each candidate idea, check whether it contradicts a known impossibility or lower bound. Consult `{{REAPER_SKILL_DIR}}/references/impossibility-results.md` for the domain-relevant impossibility results and lower bounds. +For each candidate idea, check whether it contradicts a known impossibility or lower bound. Consult `../reaper/references/impossibility-results.md` for the domain-relevant impossibility results and lower bounds. If a candidate contradicts a known impossibility: 1. Flag it explicitly with a warning @@ -109,7 +98,7 @@ If a candidate contradicts a known impossibility: ### 4. Prioritize (Hamming: Importance Filter) -Not all ideas are equally worth investigating. Rank by consequence — ask: "If we resolved this idea, who would care and why?" Consult `{{REAPER_SKILL_DIR}}/references/model.md` for domain-specific examples of how to rank by importance. +Not all ideas are equally worth investigating. Rank by consequence — ask: "If we resolved this idea, who would care and why?" Consult `../reaper/references/model.md` for domain-specific examples of how to rank by importance. ### 5. Write Output diff --git a/skills/clarify-goal/SKILL.md b/skills/clarify-goal/SKILL.md index 85352f8..4e97a7a 100644 --- a/skills/clarify-goal/SKILL.md +++ b/skills/clarify-goal/SKILL.md @@ -3,6 +3,7 @@ name: clarify-goal description: "Ask the user targeted clarifying questions about their research goal before the pipeline runs. Use when the research goal is vague, ambiguous, or missing key context (e.g., which sections to focus on, threat model assumptions, what 'broken' means). Works with or without a paper." user-invocable: true argument-hint: "\"\" [paper-path]" +license: Apache-2.0 --- # Clarify Goal diff --git a/skills/critique/SKILL.md b/skills/critique/SKILL.md index 6109ae6..00c822c 100644 --- a/skills/critique/SKILL.md +++ b/skills/critique/SKILL.md @@ -3,6 +3,8 @@ name: critique description: "Provide critique on investigation results via human feedback, Codex consultation, or self-review. Can trigger additional investigation cycles for deepen/explore feedback. Use when iterating on research, requesting AI review, or providing human feedback." user-invocable: true argument-hint: "\"\" | --codex | --self" +license: Apache-2.0 +compatibility: "--codex mode requires an MCP-capable host with the codex-cli MCP server configured; --self and human-feedback modes have no extra requirements." --- # Critique @@ -24,18 +26,6 @@ critique --codex critique --self ``` -## Path Resolution Protocol - -This skill references files in sibling skills. **`{{REAPER_SKILL_DIR}}`** below is a template placeholder — **you MUST substitute it with the absolute install path of the `/reaper` skill before reading, or the read will fail.** Common install locations: - -- `~/.claude/skills/reaper/` (Claude Code) -- `~/.cursor/skills/reaper/` (Cursor) -- `~/.agents/skills/reaper/` (Codex CLI, Cline, Gemini CLI, Copilot, OpenCode, Warp, Goose, Replit — universal target) -- `~/.continue/skills/reaper/` (Continue) -- `~/.windsurf/skills/reaper/` (Windsurf) -- `/skills/reaper/` (during repo development) - -**Sibling-skill dependency**: This skill assumes the full `/reaper` package was installed together (`npx skills add SebastianElvis/reaper`). Single-skill installs will fail to resolve sibling references. ## Inputs @@ -98,7 +88,7 @@ For **deepen** and **explore**, after completing the cycles, the orchestrator sh Consult an external AI (OpenAI Codex via MCP) for an independent second opinion on the current investigation state. This establishes an automated feedback loop where Codex plays **devil's advocate** or provides **alternative inspiration**. -See `{{REAPER_SKILL_DIR}}/references/codex-consultation.md` (placeholder defined in the Path Resolution Protocol section above) for MCP setup, fallback behavior, session continuity, and context compression rules. The critique skill's Codex mode is the most thorough consultation — other skills have lighter-weight checkpoint consultations. +See `../reaper/references/codex-consultation.md` for MCP setup, fallback behavior, session continuity, and context compression rules. The critique skill's Codex mode is the most thorough consultation — other skills have lighter-weight checkpoint consultations. ### Determining the Role diff --git a/skills/formalize-problem/SKILL.md b/skills/formalize-problem/SKILL.md index 9ff7c17..c167950 100644 --- a/skills/formalize-problem/SKILL.md +++ b/skills/formalize-problem/SKILL.md @@ -3,6 +3,7 @@ name: formalize-problem description: "Formalize a research question into precise, testable hypotheses with model assumptions, core properties, and explicit success/failure conditions. Use when asked to formalize, define, or scope a research problem after paper analysis." user-invocable: true argument-hint: "" +license: Apache-2.0 --- # Formalize Problem @@ -17,18 +18,6 @@ Invoke this skill by name with the research goal as a quoted string. On slash-co formalize-problem "determine if the security proof in Section 4 holds under asynchrony" ``` -## Path Resolution Protocol - -This skill references files in sibling skills. **`{{REAPER_SKILL_DIR}}`** below is a template placeholder — **you MUST substitute it with the absolute install path of the `/reaper` skill before reading, or the read will fail.** Common install locations: - -- `~/.claude/skills/reaper/` (Claude Code) -- `~/.cursor/skills/reaper/` (Cursor) -- `~/.agents/skills/reaper/` (Codex CLI, Cline, Gemini CLI, Copilot, OpenCode, Warp, Goose, Replit — universal target) -- `~/.continue/skills/reaper/` (Continue) -- `~/.windsurf/skills/reaper/` (Windsurf) -- `/skills/reaper/` (during repo development) - -**Sibling-skill dependency**: This skill assumes the full `/reaper` package was installed together (`npx skills add SebastianElvis/reaper`). Single-skill installs will fail to resolve sibling references. ## Instructions @@ -48,21 +37,21 @@ What exactly needs to be resolved? Be specific. "Is this protocol secure?" is to ### 3. Pin Down Model Assumptions (must be unambiguous before hypotheses) -Pin down every dimension of the system/trust model. If any dimension is left vague, the investigation will produce ambiguous results. Consult `{{REAPER_SKILL_DIR}}/references/model.md` for the domain-appropriate checklist of dimensions that must be specified. Every field must have a concrete answer, not "TBD". +Pin down every dimension of the system/trust model. If any dimension is left vague, the investigation will produce ambiguous results. Consult `../reaper/references/model.md` for the domain-appropriate checklist of dimensions that must be specified. Every field must have a concrete answer, not "TBD". Every hypothesis must reference these model assumptions by specifying which parameters it holds under. A hypothesis that states a claim without pinning every relevant dimension is rejected. ### 4. Apply Importance Filter (Hamming) -Not all questions are equally worth investigating. Prioritize by consequence — ask: "If we resolved this question, who would care and why?" Consult `{{REAPER_SKILL_DIR}}/references/model.md` for domain-specific examples of how to rank by importance. +Not all questions are equally worth investigating. Prioritize by consequence — ask: "If we resolved this question, who would care and why?" Consult `../reaper/references/model.md` for domain-specific examples of how to rank by importance. ### 5. Apply Gap-Finding (Qian) -Map the dimensions of existing work and find unexplored combinations. Consult `{{REAPER_SKILL_DIR}}/references/model.md` for the domain-appropriate gap-finding matrix dimensions. Which cells in this matrix are empty? Those are candidate hypotheses. +Map the dimensions of existing work and find unexplored combinations. Consult `../reaper/references/model.md` for the domain-appropriate gap-finding matrix dimensions. Which cells in this matrix are empty? Those are candidate hypotheses. ### 6. Screen Against Known Impossibilities -For each hypothesis, check whether it contradicts a known impossibility or lower bound. Consult `{{REAPER_SKILL_DIR}}/references/impossibility-results.md` for the domain-relevant impossibility results and lower bounds. +For each hypothesis, check whether it contradicts a known impossibility or lower bound. Consult `../reaper/references/impossibility-results.md` for the domain-relevant impossibility results and lower bounds. If a hypothesis asks to prove something that an impossibility result rules out: 1. **Flag it explicitly** in the hypothesis with a warning @@ -71,7 +60,7 @@ If a hypothesis asks to prove something that an impossibility result rules out: ### 7. Enforce Definitional Hygiene -Each core property listed in the output must be stated precisely. Consult `{{REAPER_SKILL_DIR}}/references/definitional-standards.md` for the domain-appropriate acceptable definition forms. Informal or ambiguous terms without formal definitions are NOT acceptable — different papers define the same terms differently, so pin it down. If the paper under analysis uses informal definitions, formalize them explicitly and note that you are doing so. +Each core property listed in the output must be stated precisely. Consult `../reaper/references/definitional-standards.md` for the domain-appropriate acceptable definition forms. Informal or ambiguous terms without formal definitions are NOT acceptable — different papers define the same terms differently, so pin it down. If the paper under analysis uses informal definitions, formalize them explicitly and note that you are doing so. ### 8. Write Output @@ -84,7 +73,7 @@ Write to `reaper-workspace/notes/problem-statement.md`: [Restate the goal precisely] ## Model Assumptions -[One field per dimension from `{{REAPER_SKILL_DIR}}/references/model.md`. Every dimension must have a concrete answer.] +[One field per dimension from `../reaper/references/model.md`. Every dimension must have a concrete answer.] ## Security Properties Under Investigation [What must hold? List each property with its formal definition or reference.] diff --git a/skills/investigate/SKILL.md b/skills/investigate/SKILL.md index 27e1c70..c79cfb5 100644 --- a/skills/investigate/SKILL.md +++ b/skills/investigate/SKILL.md @@ -3,6 +3,8 @@ name: investigate description: "Run investigation cycles that test hypotheses through proof verification, counterexample search, or security analysis, with keep-or-discard discipline. Use when asked to investigate, verify, prove, or disprove claims." user-invocable: true argument-hint: "[number-of-cycles]" +license: Apache-2.0 +compatibility: "Best on hosts with parallel-subagent primitives (e.g. Claude Code's Agent tool); falls back to sequential execution otherwise." --- # Investigate @@ -35,20 +37,8 @@ Default: 5 cycles if no argument given. - `reaper-workspace/notes/paper-summary.md` — the source paper (if provided) - `reaper-workspace/notes/literature.md` — known prior work (organized by same-goal and same-approach) - `reaper-workspace/papers/` — downloaded PDFs and per-paper notes (`-notes.md`) from the literature review -- `{{REAPER_SKILL_DIR}}/references/methodology.md` — proof/analysis patterns +- `../reaper/references/methodology.md` — proof/analysis patterns -## Path Resolution Protocol - -This skill references files in sibling skills. **`{{REAPER_SKILL_DIR}}`** above and below is a template placeholder — **you MUST substitute it with the absolute install path of the `/reaper` skill before reading, or the read will fail.** Common install locations: - -- `~/.claude/skills/reaper/` (Claude Code) -- `~/.cursor/skills/reaper/` (Cursor) -- `~/.agents/skills/reaper/` (Codex CLI, Cline, Gemini CLI, Copilot, OpenCode, Warp, Goose, Replit — universal target) -- `~/.continue/skills/reaper/` (Continue) -- `~/.windsurf/skills/reaper/` (Windsurf) -- `/skills/reaper/` (during repo development) - -**Sibling-skill dependency**: This skill assumes the full `/reaper` package was installed together (`npx skills add SebastianElvis/reaper`). Single-skill installs will fail to resolve sibling references. ## The Batch Loop @@ -99,7 +89,7 @@ For a new hypothesis, create `reaper-workspace/investigations/NNN-/` where Do the actual research. This is the core intellectual work. Depending on the hypothesis: -- **Proof verification**: Check each step of an existing proof. Look for gaps, implicit assumptions, boundary cases. Consult `{{REAPER_SKILL_DIR}}/references/methodology.md` for patterns. +- **Proof verification**: Check each step of an existing proof. Look for gaps, implicit assumptions, boundary cases. Consult `../reaper/references/methodology.md` for patterns. - **Proof attempt**: Try to prove the claim. Start with the simplest approach. If it works, check if a simpler proof exists. All proofs must follow the formal proof structure below. - **Counterexample search**: Try to disprove the claim. Start small (2 parties, 1 round). Construct a specific adversary strategy and execution trace. - **Security analysis**: Enumerate threat models, check if reductions go through, verify simulator constructions. Security proofs must follow the formal proof structure below. @@ -141,7 +131,7 @@ For theoretical research (proving properties, security guarantees, or performanc **Proof technique:** ``` -Consult `{{REAPER_SKILL_DIR}}/references/methodology.md` for the proof techniques catalog, reduction quality gate, and performance sanity checks. State the chosen proof technique in the proof header. If it doesn't work after a genuine attempt, log which technique failed and why, then try an alternative in the next cycle. +Consult `../reaper/references/methodology.md` for the proof techniques catalog, reduction quality gate, and performance sanity checks. State the chosen proof technique in the proof header. If it doesn't work after a genuine attempt, log which technique failed and why, then try an alternative in the next cycle. Requirements for formal proofs: @@ -184,7 +174,7 @@ When a proof issue is found, do not just say "found a gap." Classify it: ##### Composition Awareness -When a core property is confirmed, note the composition implications. Consult `{{REAPER_SKILL_DIR}}/references/definitional-standards.md` for domain-specific composition considerations (e.g., rewinding, shared setup, standalone vs compositional security). +When a core property is confirmed, note the composition implications. Consult `../reaper/references/definitional-standards.md` for domain-specific composition considerations (e.g., rewinding, shared setup, standalone vs compositional security). Log composition limitations in the investigation's `analysis.md` even if the original hypothesis didn't ask about composition — this is critical context for the final report. @@ -272,7 +262,7 @@ Run all N cycles. The only valid early stop is **genuine convergence**: all hypo ## When Stuck -If a cycle is going nowhere, follow the escalation protocol in `{{REAPER_SKILL_DIR}}/references/methodology.md` (section "When Stuck: 8-Step Escalation"). The steps progress from re-reading existing materials, through searching for new literature (see `{{REAPER_SKILL_DIR}}/references/search-tools.md` for search commands, which use the `arxiv.py` and `iacr.py` scripts in the `/search-paper` skill), to trying radically different approaches. +If a cycle is going nowhere, follow the escalation protocol in `../reaper/references/methodology.md` (section "When Stuck: 8-Step Escalation"). The steps progress from re-reading existing materials, through searching for new literature (see `../reaper/references/search-tools.md` for search commands, which use the `arxiv.py` and `iacr.py` scripts in the `/search-paper` skill), to trying radically different approaches. When searching for new literature mid-investigation, download relevant papers to `reaper-workspace/papers/`, write per-paper notes (`-notes.md`), and **integrate findings into `reaper-workspace/notes/literature.md` inline** — add new entries to the appropriate existing sections rather than appending a separate "Mid-Investigation Additions" section. Log the search as a cycle with action-type `literature-search` in `notes/results.md`. diff --git a/skills/reaper/SKILL.md b/skills/reaper/SKILL.md index b343af3..1f59afa 100644 --- a/skills/reaper/SKILL.md +++ b/skills/reaper/SKILL.md @@ -3,6 +3,8 @@ name: reaper description: "Run the full Reaper research pipeline: analyze a paper (optional), review literature, formalize the problem, investigate hypotheses with critique loops, and synthesize a report. Use when given a research goal, optionally with a paper." user-invocable: true argument-hint: "\"\" [paper-path] [--codex]" +license: Apache-2.0 +compatibility: "Requires python3 with arxiv, requests, beautifulsoup4 packages, internet access, and PDF reading capability. The --codex flag requires an MCP-capable host." --- # Reaper: AI-Native Research Pipeline diff --git a/skills/reaper/references/search-tools.md b/skills/reaper/references/search-tools.md index c376669..1adb620 100644 --- a/skills/reaper/references/search-tools.md +++ b/skills/reaper/references/search-tools.md @@ -2,24 +2,12 @@ Reaper uses the `/search-paper` skill for all academic paper search, citation graph traversal, and publication-venue resolution. The skill ships five Python scripts under one directory; this document catalogs them and shows the common workflows. -## Path Resolution Protocol - -The scripts referenced below live in the sibling `/search-paper` skill. The placeholder **`{{SEARCH_PAPER_SKILL_DIR}}`** below is a template token — **you MUST substitute it with the absolute install path of the sibling skill before invoking, or the exec will fail.** Common install locations: - -- `~/.claude/skills/search-paper/` (Claude Code) -- `~/.cursor/skills/search-paper/` (Cursor) -- `~/.agents/skills/search-paper/` (Codex CLI, Cline, Gemini CLI, Copilot, OpenCode, Warp, Goose, Replit — universal target) -- `~/.continue/skills/search-paper/` (Continue) -- `~/.windsurf/skills/search-paper/` (Windsurf) -- `/skills/search-paper/` (during repo development) - -**Sibling-skill dependency**: This reference assumes the full `/reaper` package was installed together (`npx skills add SebastianElvis/reaper`) so that `reaper/` and `search-paper/` are co-located in your agent's skills folder. ## Scripts ### `arxiv.py` — arXiv preprint server -**Location**: `{{SEARCH_PAPER_SKILL_DIR}}/arxiv.py` +**Location**: `../../search-paper/arxiv.py` **Dependencies**: `pip install arxiv` | Command | Purpose | Key Parameters | @@ -41,7 +29,7 @@ The scripts referenced below live in the sibling `/search-paper` skill. The plac ### `iacr.py` — IACR ePrint archive -**Location**: `{{SEARCH_PAPER_SKILL_DIR}}/iacr.py` +**Location**: `../../search-paper/iacr.py` **Dependencies**: `pip install requests beautifulsoup4` | Command | Purpose | Key Parameters | @@ -58,7 +46,7 @@ The scripts referenced below live in the sibling `/search-paper` skill. The plac ### `semantic_scholar.py` — Semantic Scholar metadata -**Location**: `{{SEARCH_PAPER_SKILL_DIR}}/semantic_scholar.py` +**Location**: `../../search-paper/semantic_scholar.py` **Dependencies**: `pip install requests` | Command | Purpose | Key Parameters | @@ -73,7 +61,7 @@ The scripts referenced below live in the sibling `/search-paper` skill. The plac ### `dblp.py` — DBLP metadata -**Location**: `{{SEARCH_PAPER_SKILL_DIR}}/dblp.py` +**Location**: `../../search-paper/dblp.py` **Dependencies**: `pip install requests` | Command | Purpose | Key Parameters | @@ -84,7 +72,7 @@ The scripts referenced below live in the sibling `/search-paper` skill. The plac ### `openalex.py` — OpenAlex metadata -**Location**: `{{SEARCH_PAPER_SKILL_DIR}}/openalex.py` +**Location**: `../../search-paper/openalex.py` **Dependencies**: `pip install requests` | Command | Purpose | Key Parameters | @@ -149,12 +137,12 @@ The authoritative layered protocol lives in the `/search-paper` skill's own `SKI 1. Run a focused query on the specific question that arose: ```bash - python {{SEARCH_PAPER_SKILL_DIR}}/iacr.py search "exact technical question" --max-results 5 - python {{SEARCH_PAPER_SKILL_DIR}}/arxiv.py search "exact technical question" --max-results 5 + python3 ../../search-paper/iacr.py search "exact technical question" --max-results 5 + python3 ../../search-paper/arxiv.py search "exact technical question" --max-results 5 ``` 2. If a highly relevant paper is found, download and read it: ```bash - python {{SEARCH_PAPER_SKILL_DIR}}/arxiv.py download --output-dir reaper-workspace/papers/ + python3 ../../search-paper/arxiv.py download --output-dir reaper-workspace/papers/ ``` 3. Resolve its venue via the layered protocol; integrate findings into `literature.md` inline (add to appropriate existing sections) @@ -163,7 +151,7 @@ The authoritative layered protocol lives in the `/search-paper` skill's own `SKI 1. Start with a known paper's arXiv ID 2. Get references (backward) and citations (forward): ```bash - python {{SEARCH_PAPER_SKILL_DIR}}/semantic_scholar.py citations 2305.12345 --max-results 20 + python3 ../../search-paper/semantic_scholar.py citations 2305.12345 --max-results 20 ``` 3. For each highly relevant citation, recursively chase (1-2 hops max) diff --git a/skills/review-literature/SKILL.md b/skills/review-literature/SKILL.md index c767961..44c9e10 100644 --- a/skills/review-literature/SKILL.md +++ b/skills/review-literature/SKILL.md @@ -3,6 +3,8 @@ name: review-literature description: "Search for related academic work, download and read key papers, and produce a structured literature survey. Use when asked to find prior art, related papers, competing approaches, or known results for a research topic." user-invocable: true argument-hint: "" +license: Apache-2.0 +compatibility: "Requires the sibling /search-paper skill (co-installed) and internet access; PDF reading capability recommended." --- # Review Literature diff --git a/skills/search-paper/SKILL.md b/skills/search-paper/SKILL.md index 05c23b7..5ff40a2 100644 --- a/skills/search-paper/SKILL.md +++ b/skills/search-paper/SKILL.md @@ -3,6 +3,8 @@ name: search-paper description: "Find papers, download PDFs, traverse citation graphs, and resolve publication venues across arXiv, IACR ePrint, Semantic Scholar, DBLP, and OpenAlex. Use when you need to find papers, trace citations, or determine where a paper was published." user-invocable: true argument-hint: " [--source arxiv|iacr] [--max-results N]" +license: Apache-2.0 +compatibility: "Requires python3 with arxiv, requests, beautifulsoup4 packages and internet access for arXiv, IACR ePrint, Semantic Scholar, DBLP, OpenAlex." --- # Search Paper @@ -17,18 +19,6 @@ Invoke this skill by name. On slash-command hosts: `/search-paper ""`. search-paper "post-quantum threshold signatures" --source iacr --max-results 15 ``` -## Path Resolution Protocol - -This skill ships five Python scripts in the **same directory as this `SKILL.md`**. The placeholder **`{{SKILL_DIR}}`** below is a template token — **you MUST substitute it with the absolute install path of this skill before invoking, or the exec will fail.** Common install locations: - -- `~/.claude/skills/search-paper/` (Claude Code) -- `~/.cursor/skills/search-paper/` (Cursor) -- `~/.agents/skills/search-paper/` (Codex CLI, Cline, Gemini CLI, Copilot, OpenCode, Warp, Goose, Replit — universal target) -- `~/.continue/skills/search-paper/` (Continue) -- `~/.windsurf/skills/search-paper/` (Windsurf) -- `/skills/search-paper/` (during repo development) - -This skill has no sibling-skill dependencies — it ships its own scripts. ## Scripts @@ -37,10 +27,10 @@ Run via Bash. All scripts emit JSON on stdout. ### `arxiv.py` — arXiv preprint server ```bash -python {{SKILL_DIR}}/arxiv.py search "BFT consensus communication complexity" --max-results 10 --categories cs.CR,cs.DC -python {{SKILL_DIR}}/arxiv.py recent "threshold signatures" --max-results 10 --categories cs.CR -python {{SKILL_DIR}}/arxiv.py download 2305.12345 --output-dir reaper-workspace/papers/ -python {{SKILL_DIR}}/arxiv.py journal-ref 2305.12345 +python3 arxiv.py search "BFT consensus communication complexity" --max-results 10 --categories cs.CR,cs.DC +python3 arxiv.py recent "threshold signatures" --max-results 10 --categories cs.CR +python3 arxiv.py download 2305.12345 --output-dir reaper-workspace/papers/ +python3 arxiv.py journal-ref 2305.12345 ``` - `search` — array of `{arxiv_id, title, authors, year, abstract, categories, pdf_url, published, journal_ref}` sorted by relevance. @@ -51,11 +41,11 @@ python {{SKILL_DIR}}/arxiv.py journal-ref 2305.12345 ### `iacr.py` — IACR ePrint archive ```bash -python {{SKILL_DIR}}/iacr.py search "threshold signatures" --max-results 10 -python {{SKILL_DIR}}/iacr.py recent --max-results 10 -python {{SKILL_DIR}}/iacr.py download 2024/1234 --output-dir reaper-workspace/papers/ -python {{SKILL_DIR}}/iacr.py url 2024/1234 -python {{SKILL_DIR}}/iacr.py pubinfo 2024/1234 +python3 iacr.py search "threshold signatures" --max-results 10 +python3 iacr.py recent --max-results 10 +python3 iacr.py download 2024/1234 --output-dir reaper-workspace/papers/ +python3 iacr.py url 2024/1234 +python3 iacr.py pubinfo 2024/1234 ``` - `search` — array of `{eprint_id, title, authors, year, abstract, publication_info, venue, pdf_url, url}`. Top 5 results are enriched with metadata from the paper page (including `publication_info`). @@ -66,9 +56,9 @@ python {{SKILL_DIR}}/iacr.py pubinfo 2024/1234 ### `semantic_scholar.py` — Semantic Scholar metadata ```bash -python {{SKILL_DIR}}/semantic_scholar.py venue --arxiv 2305.12345 -python {{SKILL_DIR}}/semantic_scholar.py venue --title "HotStuff: BFT Consensus in the Lens of Blockchain" -python {{SKILL_DIR}}/semantic_scholar.py citations 2305.12345 --max-results 20 +python3 semantic_scholar.py venue --arxiv 2305.12345 +python3 semantic_scholar.py venue --title "HotStuff: BFT Consensus in the Lens of Blockchain" +python3 semantic_scholar.py citations 2305.12345 --max-results 20 ``` - `venue` — looks up the publication venue by arXiv ID (preferred when available — exact match) or by title (fuzzy match via `/paper/search/match`). Returns `{found, venue, venue_full, venue_type, year, title, authors}`. @@ -77,7 +67,7 @@ python {{SKILL_DIR}}/semantic_scholar.py citations 2305.12345 --max-results 20 ### `dblp.py` — DBLP (CS-focused) ```bash -python {{SKILL_DIR}}/dblp.py venue "HotStuff: BFT Consensus" --author "Yin" +python3 dblp.py venue "HotStuff: BFT Consensus" --author "Yin" ``` - `venue` — title (+ optional author surname) lookup. DBLP is authoritative for CS conference and journal venues. @@ -85,7 +75,7 @@ python {{SKILL_DIR}}/dblp.py venue "HotStuff: BFT Consensus" --author "Yin" ### `openalex.py` — OpenAlex (broad coverage) ```bash -python {{SKILL_DIR}}/openalex.py venue "HotStuff: BFT Consensus in the Lens of Blockchain" +python3 openalex.py venue "HotStuff: BFT Consensus in the Lens of Blockchain" ``` - `venue` — title-based lookup. Use when DBLP doesn't cover the venue (non-CS, niche workshops, books). @@ -123,10 +113,10 @@ A paper's archive ID (arXiv, ePrint) is *not* its publication venue. Resolve the ```bash # arXiv-known papers -python {{SKILL_DIR}}/semantic_scholar.py venue --arxiv +python3 semantic_scholar.py venue --arxiv # ePrint-only papers -python {{SKILL_DIR}}/semantic_scholar.py venue --title "" +python3 semantic_scholar.py venue --title "" ``` If `found: true` and `venue` is non-empty → done. Record `source = "semantic_scholar"`. @@ -137,10 +127,10 @@ Authors sometimes mark the venue on their own preprint: ```bash # arXiv: the journal_ref field -python {{SKILL_DIR}}/arxiv.py journal-ref +python3 arxiv.py journal-ref # ePrint: the "Publication info" line -python {{SKILL_DIR}}/iacr.py pubinfo +python3 iacr.py pubinfo ``` If a non-empty `journal_ref` / `publication_info` is returned → done. Record `source = "arxiv_journal_ref"` or `"iacr_pubinfo"`. @@ -148,7 +138,7 @@ If a non-empty `journal_ref` / `publication_info` is returned → done. Record ` ### Layer 3 — DBLP (CS-authoritative title+author search) ```bash -python {{SKILL_DIR}}/dblp.py venue "" --author "<first author surname>" +python3 dblp.py venue "<title>" --author "<first author surname>" ``` If `found: true` → done. Record `source = "dblp"`. @@ -156,7 +146,7 @@ If `found: true` → done. Record `source = "dblp"`. ### Layer 4 — OpenAlex (broad coverage) ```bash -python {{SKILL_DIR}}/openalex.py venue "<title>" +python3 openalex.py venue "<title>" ``` If `found: true` → done. Record `source = "openalex"`. diff --git a/skills/search-paper/arxiv.py b/skills/search-paper/arxiv.py index 7b3e479..ba5714e 100644 --- a/skills/search-paper/arxiv.py +++ b/skills/search-paper/arxiv.py @@ -2,10 +2,10 @@ """arXiv platform driver: search papers, list recent submissions, download PDFs, read journal_ref field. Usage: - python arxiv.py search "<query>" [--max-results N] [--categories cat1,cat2] - python arxiv.py recent ["<query>"] [--max-results N] [--categories cat1,cat2] - python arxiv.py download <arxiv_id> [--output-dir DIR] - python arxiv.py journal-ref <arxiv_id> + python3 arxiv.py search "<query>" [--max-results N] [--categories cat1,cat2] + python3 arxiv.py recent ["<query>"] [--max-results N] [--categories cat1,cat2] + python3 arxiv.py download <arxiv_id> [--output-dir DIR] + python3 arxiv.py journal-ref <arxiv_id> Requires: pip install arxiv """ diff --git a/skills/search-paper/dblp.py b/skills/search-paper/dblp.py index ea8e637..8a62185 100644 --- a/skills/search-paper/dblp.py +++ b/skills/search-paper/dblp.py @@ -2,7 +2,7 @@ """DBLP driver: title+author venue lookup. Authoritative for CS venues. Usage: - python dblp.py venue "<title>" [--author "<surname>"] + python3 dblp.py venue "<title>" [--author "<surname>"] Requires: pip install requests """ diff --git a/skills/search-paper/iacr.py b/skills/search-paper/iacr.py index 67e0271..12b0f36 100644 --- a/skills/search-paper/iacr.py +++ b/skills/search-paper/iacr.py @@ -2,11 +2,11 @@ """IACR ePrint platform driver: search, recent, download, url, pubinfo. Usage: - python iacr.py search "<query>" [--max-results N] - python iacr.py recent [--max-results N] - python iacr.py download <eprint_id> [--output-dir DIR] - python iacr.py url <eprint_id> - python iacr.py pubinfo <eprint_id> + python3 iacr.py search "<query>" [--max-results N] + python3 iacr.py recent [--max-results N] + python3 iacr.py download <eprint_id> [--output-dir DIR] + python3 iacr.py url <eprint_id> + python3 iacr.py pubinfo <eprint_id> Requires: pip install requests beautifulsoup4 """ diff --git a/skills/search-paper/openalex.py b/skills/search-paper/openalex.py index c8b6ad7..11e4046 100644 --- a/skills/search-paper/openalex.py +++ b/skills/search-paper/openalex.py @@ -2,7 +2,7 @@ """OpenAlex driver: title-based venue lookup. Broad coverage beyond CS. Usage: - python openalex.py venue "<title>" + python3 openalex.py venue "<title>" Requires: pip install requests """ diff --git a/skills/search-paper/semantic_scholar.py b/skills/search-paper/semantic_scholar.py index 6015064..3ef021f 100644 --- a/skills/search-paper/semantic_scholar.py +++ b/skills/search-paper/semantic_scholar.py @@ -2,9 +2,9 @@ """Semantic Scholar driver: venue lookup and citation graph. Usage: - python semantic_scholar.py venue --arxiv <arxiv_id> - python semantic_scholar.py venue --title "<title>" [--author "<surname>"] - python semantic_scholar.py citations <arxiv_id> [--max-results N] + python3 semantic_scholar.py venue --arxiv <arxiv_id> + python3 semantic_scholar.py venue --title "<title>" [--author "<surname>"] + python3 semantic_scholar.py citations <arxiv_id> [--max-results N] Requires: pip install requests """ diff --git a/skills/synthesize/SKILL.md b/skills/synthesize/SKILL.md index 35141c4..4d560ff 100644 --- a/skills/synthesize/SKILL.md +++ b/skills/synthesize/SKILL.md @@ -3,6 +3,7 @@ name: synthesize description: "Generate a research paper from investigation results, structured as a formal academic paper with definitions, theorems, lemmas, and proofs. Use when asked to synthesize, summarize, or write up research findings after investigation cycles." user-invocable: true argument-hint: "" +license: Apache-2.0 --- # Synthesize diff --git a/tests/test_skills_structure.py b/tests/test_skills_structure.py index 35e320b..3e8aa58 100644 --- a/tests/test_skills_structure.py +++ b/tests/test_skills_structure.py @@ -114,11 +114,11 @@ def test_review_literature_delegates_to_search_paper(): assert script not in content, ( f"review-literature references {script} directly; delegate to /search-paper instead" ) - # Must not carry any SKILL_DIR placeholders — delegation removed the need for them. - placeholder_pattern = re.compile(r"\{\{[A-Z_]*SKILL_DIR\}\}") - assert not placeholder_pattern.search(content), ( - "review-literature still uses {{*_SKILL_DIR}} placeholders; after the /search-paper " - "delegation refactor it must be fully path-agnostic" + # Must remain fully path-agnostic — the review-literature skill never + # reaches into another skill's filesystem directly. + assert "../search-paper" not in content and "../reaper" not in content, ( + "review-literature should not include sibling-skill paths; it " + "delegates by skill name only." ) @@ -186,11 +186,12 @@ def test_readme_lists_search_skills(): # --------------------------------------------------------------------------- # Path-portability regression tests (host-agnostic skills package) # --------------------------------------------------------------------------- +# +# Per the Agent Skills specification (https://agentskills.io/specification), +# file references inside a skill must use **relative paths from the skill +# root**. Cross-skill references rely on `npx skills add` co-installing all +# skills as siblings under the host's skills directory. -# Skill files that ship inter-skill or intra-skill path references. Each is -# checked for both: (a) no relative `python skills/...` invocations have crept -# back in, and (b) every {{*_SKILL_DIR}} placeholder used in the file is also -# defined somewhere in the file. PATH_AWARE_SKILLS = [ "skills/reaper/SKILL.md", "skills/reaper/references/search-tools.md", @@ -207,100 +208,62 @@ def test_readme_lists_search_skills(): ] -def test_no_relative_python_skills_invocations(): - """Regression: skills must never invoke `python skills/<name>/...` directly. - - Such relative paths only resolve if the user happens to be running the - agent from the repo root. After `npx skills add`, the scripts live under - a per-host install dir (e.g. ~/.agents/skills/, ~/.cursor/skills/), so - skills must use the {{*_SKILL_DIR}} placeholders that the agent - substitutes at execution time. +def test_no_skill_dir_placeholders(): + """The `{{*SKILL_DIR}}` placeholder convention has been replaced by + spec-compliant relative paths. Regression: no placeholders should + reappear in any skill or reference file. """ - pattern = re.compile(r"python\s+skills/") + placeholder_pattern = re.compile(r"\{\{[A-Z_]*SKILL_DIR\}\}") offenders = [] for path in PATH_AWARE_SKILLS: p = Path(path) if not p.exists(): continue - content = p.read_text() - for m in pattern.finditer(content): - # Find the offending line - line_no = content[: m.start()].count("\n") + 1 - offenders.append(f"{path}:{line_no}") + if placeholder_pattern.search(p.read_text()): + offenders.append(path) assert not offenders, ( - "Found relative `python skills/...` invocations — these break under " - "npx skills install (scripts live in per-host install dirs, not " - "under skills/). Use the {{REAPER_SKILL_DIR}} / " - "{{SEARCH_PAPER_SKILL_DIR}} / {{SKILL_DIR}} placeholders instead. " + "Found {{*SKILL_DIR}} placeholders. Use relative paths instead " + "(e.g. `../reaper/references/methodology.md` for sibling-skill " + "references, bare filename for same-directory scripts). " "Offenders: " + ", ".join(offenders) ) -def test_skill_dir_placeholders_are_defined(): - """Every {{*SKILL_DIR}} placeholder used in a skill must also be defined - in that same file (so the agent has the substitution rules co-located - with the references that need substituting). A 'definition' is any - mention of the placeholder inside a Path-Resolution-style block — we - detect this by requiring the placeholder appears in a paragraph that - also contains the word 'install' or 'substitute' or 'resolve' (the - standardized preamble vocabulary). - - Matches both the multi-skill form ({{REAPER_SKILL_DIR}}, - {{SEARCH_PAPER_SKILL_DIR}}) and the own-directory form ({{SKILL_DIR}}) - used by leaf skills like /search-paper. - """ - placeholder_pattern = re.compile(r"\{\{([A-Z_]*SKILL_DIR)\}\}") - # Words that appear in a definition paragraph (per the standardized - # Path Resolution Protocol preamble). - definition_keywords = ("install", "substitute", "resolve", "denote", "absolute") - - failures = [] +def test_no_python2_invocations(): + """Skills should invoke `python3` rather than `python` for portability + across hosts where `python` may not exist.""" + pattern = re.compile(r"\bpython (?=[a-zA-Z_./])") + offenders = [] for path in PATH_AWARE_SKILLS: p = Path(path) if not p.exists(): continue content = p.read_text() - used = set(placeholder_pattern.findall(content)) - if not used: - continue - # Split into paragraphs and find which paragraphs define a placeholder - paragraphs = re.split(r"\n\s*\n", content) - defined = set() - for para in paragraphs: - if not any(kw in para.lower() for kw in definition_keywords): - continue - for ph in placeholder_pattern.findall(para): - defined.add(ph) - missing = used - defined - if missing: - failures.append(f"{path}: uses {sorted(missing)} but never defines them") - assert not failures, ( - "Some skills reference {{*_SKILL_DIR}} placeholders without a local " - "definition paragraph. Each skill that uses a placeholder must " - "include a Path Resolution Protocol section that lists install " - "locations and tells the agent to substitute it. Failures:\n " - + "\n ".join(failures) + for m in pattern.finditer(content): + line_no = content[: m.start()].count("\n") + 1 + offenders.append(f"{path}:{line_no}") + assert not offenders, ( + "Found `python ...` invocations — use `python3 ...` for portability. " + "Offenders: " + ", ".join(offenders) ) -def test_path_resolution_protocol_section_present(): - """Skills that use {{*SKILL_DIR}} placeholders must declare a - 'Path Resolution Protocol' section so the convention is visually - obvious to readers and downstream auditors. Matches both the - multi-skill placeholders (e.g. {{REAPER_SKILL_DIR}}) and the leaf - own-directory form ({{SKILL_DIR}}).""" - placeholder_pattern = re.compile(r"\{\{[A-Z_]*SKILL_DIR\}\}") - failures = [] +def test_no_relative_python_skills_invocations(): + """Skills must never invoke `python3 skills/<name>/...` from inside a + SKILL.md — such paths only resolve at the repo root, not after install. + """ + pattern = re.compile(r"python3?\s+skills/") + offenders = [] for path in PATH_AWARE_SKILLS: p = Path(path) if not p.exists(): continue content = p.read_text() - if not placeholder_pattern.search(content): - continue - if "Path Resolution Protocol" not in content: - failures.append(path) - assert not failures, ( - "Skills that use path placeholders must declare a 'Path Resolution " - "Protocol' section. Missing in: " + ", ".join(failures) + for m in pattern.finditer(content): + line_no = content[: m.start()].count("\n") + 1 + offenders.append(f"{path}:{line_no}") + assert not offenders, ( + "Found `python skills/...` invocations — use relative paths from " + "the skill root instead (e.g. `../search-paper/arxiv.py`). " + "Offenders: " + ", ".join(offenders) )