---
name: researcher
description: Researches codebase, project state, and external knowledge using local search, SF database queries, and web search. Use when investigating an unfamiliar subsystem, understanding project milestones and requirements, or gathering evidence for planning. Produces structured research reports.
---

<objective>
Research a topic using four complementary information sources, in priority order:
1. **Native LSP tool + local search** (`lsp`, `rg`, `find`, `ls`) — use FIRST for code exploration
2. **sift** (hybrid BM25+vector local search) — use when LSP/rg is not enough
3. **SF project database** (sqlite3) — use for project state (milestones, requirements, decisions)
4. **Web search** — use for external documentation and current information

This skill is the first step before planning — it produces the evidence base that drives good decisions. Without research, agents plan from assumptions; with this skill, they plan from evidence.
</objective>

<read_only_discipline>

This is a **read-only** skill. Research produces a report; it does not modify the repo, the database, or external state.

Strictly prohibited while running this skill:

- File creation, modification, or deletion (no `Write`, `Edit`, `NotebookEdit`, `touch`, `rm`, `mv`, `cp`).
- Bash redirects or heredocs that write files: `>`, `>>`, `tee`, `cat <<EOF > file`, `python -c "open(...).write(...)"`. The shell back-door does not bypass the read-only contract.
- DB writes: `sqlite3 .sf/sf.db "INSERT|UPDATE|DELETE|DROP|CREATE ..."`. Use `SELECT` only.
- Git write operations: `add`, `commit`, `push`, `merge`, `rebase`, `checkout -b`, `branch -d`.
- Package installs: `npm install`, `pip install`, `cargo add`.
- Spawning subagents that perform any of the above on the researcher's behalf — the prohibition applies to delegated actions as well.

The single allowed write is the research report itself, written via the parent agent's tools after this skill returns its findings — not by the researcher mid-skill. Communicate findings as a structured report in the response, not by writing intermediate scratch files.

If a research question genuinely requires a write to answer (e.g., "does X actually work?" requires running a script), surface that as a finding labelled "requires execution" so the parent can dispatch a `worker` subagent — do not perform the write yourself.

</read_only_discipline>

<quick_start>

**Native code intelligence — USE FIRST for code exploration:**
```bash
# Workspace symbol search
lsp action=symbols query=resolveSubagentLaunchSpec

# Document symbols
lsp action=symbols file=src/resources/extensions/subagent/index.ts

# Go to definition at a line/symbol
lsp action=definition file=src/resources/extensions/subagent/index.ts line=42 symbol=resolveSubagentLaunchSpec

# Find references/callers
lsp action=references file=src/resources/extensions/subagent/index.ts line=42 symbol=resolveSubagentLaunchSpec
lsp action=incoming_calls file=src/resources/extensions/subagent/index.ts line=42 symbol=resolveSubagentLaunchSpec

# Fast text/file search
rg -n "codebase_search|resolveSubagentLaunchSpec" src packages
rg --files src/resources/extensions/sf/skills
```

**Local code search — sift (hybrid BM25+vector search):**
```bash
sift search --strategy path-hybrid "authentication middleware"
sift search --strategy hybrid --limit 5 "where is the write gate registered"
```

**SF project database queries:**
```bash
# Current milestone and slices
sqlite3 .sf/sf.db "SELECT id, title, status FROM milestones WHERE status='active'"

# All requirements
sqlite3 .sf/sf.db "SELECT id, class, status, description FROM requirements"

# Recent decisions
sqlite3 .sf/sf.db "SELECT id, scope, decision FROM decisions ORDER BY seq DESC LIMIT 10"

# Tasks by slice
sqlite3 .sf/sf.db "SELECT id, title, status FROM tasks WHERE milestone_id='M001' AND slice_id='S01'"
```

**Web search — use the search-the-web tool directly for current information.**
</quick_start>

<workflow>

## Step 1: Clarify the research goal

Before searching, identify what you need to know:
- **Code exploration** (finding functions, types, references) → use native `lsp` first, then `rg`
- **Project state** (milestones, slices, tasks, requirements) → query the SF DB
- **Current external information** → use web search
- **All of the above** → combine all four sources

## Step 2: Explore code with native LSP (priority)

Use the built-in `lsp` tool for symbol-aware navigation:

```bash
# Find where a function or type is defined
lsp action=symbols query=MyFunction
lsp action=definition file=src/my-file.ts line=42 symbol=MyFunction

# Find all callers/references to a symbol
lsp action=references file=src/my-file.ts line=42 symbol=MyFunction
lsp action=incoming_calls file=src/my-file.ts line=42 symbol=MyFunction

# Read a specific file
read file=src/my-file.ts

# Grep-like search across the codebase
rg -n "TODO.*auth" src packages
```

## Step 3: Supplement with sift (when LSP/rg is not enough)

Use sift when you need semantic/hybrid search across unstructured content:

```bash
# Hybrid search for conceptual matches
sift search --strategy hybrid --limit 5 "authentication middleware token validation"
```

## Step 4: Query the SF project database

The SF database (`.sf/sf.db`) contains the canonical project state:

```bash
# List active milestones with their slices
sqlite3 .sf/sf.db "
  SELECT m.id, m.title, m.status, s.id, s.title, s.status
  FROM milestones m
  LEFT JOIN slices s ON s.milestone_id = m.id
  WHERE m.status IN ('active','planning')
  ORDER BY m.id, s.id
"

# Get requirements by status
sqlite3 .sf/sf.db "SELECT id, class, status, description FROM requirements WHERE status='active'"

# Recent decisions (most recent first)
sqlite3 .sf/sf.db "SELECT id, scope, decision, choice FROM decisions ORDER BY seq DESC LIMIT 20"

# Blocked or pending tasks
sqlite3 .sf/sf.db "SELECT id, title, status FROM tasks WHERE status IN ('blocked','pending')"

# Artifacts (plans, summaries) for a milestone
sqlite3 .sf/sf.db "SELECT path, artifact_type FROM artifacts WHERE milestone_id='M001'"
```

## Step 5: Web search for external information

Use `search-the-web` for documentation, tutorials, or current best practices:

```bash
search_the_web "Next.js 15 app router migration guide"
```

## Step 6: Synthesize into a research report

Write findings to the appropriate artifact:
- Milestone research → `.sf/milestones/{mid}/{mid}-RESEARCH.md`
- Slice research → `.sf/milestones/{mid}/slices/{sid}/{sid}-RESEARCH.md`
- Ad-hoc research → `.sf/research/{topic}.md`

**Research report structure:**
```markdown
# Research: {topic}

## Goal
What question are we answering?

## SF Project State
What does the SF DB say? (milestones, requirements, decisions relevant to this topic)

## Codebase Evidence
What did sift find? (key file:line references)

## External Knowledge
What did web search reveal?

## Findings
Bullet points of the most important discoveries

## Gaps
What is still unknown or needs verification?

## Recommendations
What should the agent do next?
```
</workflow>

<success_criteria>
- Research report written to the correct artifact path
- At least one SF DB query executed and cited
- At least one sift search executed and cited
- Findings are specific (file:line or table:row references), not generic
- Gaps identified honestly — what you could not determine
</success_criteria>

<reference_guides>

### Useful SF DB queries

```sql
-- All milestones with completion status
SELECT id, title, status, completed_at FROM milestones ORDER BY id;

-- All slices for a milestone
SELECT id, title, status, risk FROM slices WHERE milestone_id='M001' ORDER BY sequence;

-- Tasks with verification status
SELECT t.id, t.title, t.status, t.verification_status
FROM tasks t WHERE t.milestone_id='M001' AND t.slice_id='S01';

-- Open requirements
SELECT id, class, description FROM requirements WHERE status IN ('active','pending');

-- Decisions by scope
SELECT id, scope, decision FROM decisions WHERE scope='architecture' ORDER BY seq DESC;

-- Memory entries
SELECT id, category, content FROM memories ORDER BY seq DESC LIMIT 20;
```

### sift strategies

| Strategy | When to use |
|---|---|
| `path-hybrid` | Default. File path + content matching — best for most queries |
| `hybrid` | Pure content matching — when you don't care about file names |
| `page-index-hybrid` | Web-page-like content (documentation) |
| `bm25` | Exact keyword matching — fast fallback |

### DB schema reference

- `milestones` — id, title, status, vision, success_criteria (JSON), completed_at
- `slices` — milestone_id, id, title, status, risk, goal, success_criteria
- `tasks` — milestone_id, slice_id, id, title, status, one_liner, narrative, verification_result
- `requirements` — id, class, status, description, why, source, primary_owner, validation
- `decisions` — seq, id, scope, decision, choice, rationale, revisable, made_by
- `artifacts` — path, artifact_type, milestone_id, slice_id, task_id
- `memories` — id, category, content, confidence
</reference_guides>
