# Works Search Strategy Skill

## Purpose
This skill provides expert guidance for finding OpenAlex works (papers) by title and author information, using a validation-first approach to ensure high confidence matches.

## Core Strategy

### 1. Direct Search Validation Rules
When searching OpenAlex directly by title:
- **Title Match**: After normalization (lowercase, remove punctuation, collapse whitespace), titles must match exactly
- **Author Validation**: If an author last name is provided, it MUST appear in the work's author list
- **Substring Matching**: For long titles (>20 chars), accept if one title is substring of the other (handles subtitle variations)
- **Early Success**: If validation passes, return immediately—no need for further searching

### 2. Search Techniques

#### By Title
```
Use: search_by_title(title)
- Remove commas from title (interpreted as URL parameters)
- Check top 5 results for validation
- Prefer exact matches after normalization
```

#### By DOI
```
Use: search_by_doi(doi)
- Most reliable when DOI is known
- Direct lookup, no ambiguity
- Always returns correct work if valid
```

#### By Author + Title
```
Combined approach:
1. Search by title to get candidate works
2. Validate that author appears in each candidate
3. Return first validated match
```

### 3. Validation Checklist

For each candidate work, verify:
- [ ] Title matches (after normalization)
- [ ] If author specified: last name in author list
- [ ] Work has OpenAlex ID
- [ ] DOI present (if available)
- [ ] Author details extracted (ID, ORCID if specified)

### 4. Author Extraction

When finding author in work's authorships:
```python
For each authorship in work['authorships']:
    author = authorship['author']
    if normalize(author_last_name) in normalize(author['display_name']):
        Extract:
        - author['id'] → OpenAlex author ID
        - author['orcid'] → ORCID (may be None)
        Set author_found_in_work = True
```

### 5. Response Structure

Always return this exact JSON structure:
```json
{
  "status": "success" | "not_found" | "error",
  "work": {
    "openalex_id": "W1234567890",
    "doi": "10.1234/example",
    "title": "Full work title",
    "author_openalex_id": "A5023888391",
    "author_orcid": "0000-0001-2345-6789",
    "author_found_in_work": true,
    "match_confidence": "direct" | "agent"
  }
}
```

### 6. Common Pitfalls to Avoid

❌ **Don't:**
- Return a work if title doesn't match closely
- Return a work if specified author is not in author list
- Assume DOI format without checking
- Return ambiguous matches without validation

✅ **Do:**
- Normalize all strings before comparison
- Check multiple spellings/variations of author names
- Use web search to find DOI if title search fails
- Set author_found_in_work=false if author not validated

### 7. Error Handling

**Work Not Found:**
```json
{
  "status": "not_found",
  "work": null,
  "message": "No validated match found for title: ..."
}
```

**API Error:**
```json
{
  "status": "error",
  "work": null,
  "error": "OpenAlex API timeout"
}
```

### 8. Advanced: Fuzzy Title Matching

When direct search fails, try:
1. **Remove year from title** (e.g., "Study (2020)" → "Study")
2. **Remove subtitle** (e.g., "Main: Subtitle" → "Main")
3. **Try abbreviated journal names**
4. **Use web search** to find canonical title or DOI

### 9. OpenAlex Work Object Structure

Key fields to extract:
```python
work = {
    'id': 'https://openalex.org/W...',  # OpenAlex ID
    'doi': 'https://doi.org/...',        # DOI
    'title': 'Paper title',              # Full title
    'authorships': [                     # Author list
        {
            'author': {
                'id': 'https://openalex.org/A...',
                'display_name': 'Author Name',
                'orcid': 'https://orcid.org/...'
            },
            'author_position': 'first',
            'institutions': [...]
        }
    ],
    'publication_year': 2023,
    'cited_by_count': 42,
    'primary_location': {...}
}
```

### 10. Quality Assurance

Before returning success:
- ✓ OpenAlex ID present and valid
- ✓ Title is reasonable (not empty, not error message)
- ✓ If author specified: author_found_in_work = true
- ✓ If DOI present: properly formatted
- ✓ match_confidence set correctly

## Example Workflow

```
User Query: Find paper "The state of OA" by Priem, 2018

Step 1: Search OpenAlex by title
  → Found: W2741809807

Step 2: Validate title
  Candidate: "The state of OA: a large-scale analysis..."
  Query: "The state of OA"
  ✓ Match (candidate contains query)

Step 3: Validate author
  Search "Priem" in authorships
  Found: Jason Priem (A5023888391)
  ✓ Author found

Step 4: Return success
{
  "status": "success",
  "work": {
    "openalex_id": "W2741809807",
    "doi": "10.7717/peerj.4375",
    "title": "The state of OA: a large-scale analysis...",
    "author_openalex_id": "A5023888391",
    "author_orcid": "0000-0001-6187-6610",
    "author_found_in_work": true,
    "match_confidence": "agent"
  }
}
```

## Remember

**Validation First**: Better to return "not_found" than return wrong work.
**Author Safety**: If author specified but not found → not_found.
**Clear Flags**: Always set author_found_in_work accurately.
**Structured Output**: Use exact JSON schema every time.
