# Stage name → file/code resolution

When the user says *"include Three Doors in the match"* or *"add my Bang and Clang from last week"*, the skill needs to resolve a stage NAME to either:
- A bundled classifier code (becomes a `ref` entry), or
- A full Stage v2 JSON file path (becomes an `inline` entry)

This file describes the resolution order and the conventions the skill follows.

## Resolution order

For a user-provided name, check in this order and use the first match:

### 1. Bundled classifier (becomes `ref`)

Match against `references/classifier_index.md` on:
- Classifier code (e.g., `"CM 99-08"`, `"99-08"`, `"CM99-08"`) — exact match, whitespace and dash flexible
- Stage name (e.g., `"Melody Line"`, `"melody line"`) — case-insensitive substring match
- Common nickname (e.g., `"El Pres"` → CM 99-11)

If matched, emit `{ "ref": "CM 99-08" }`. No file read needed.

### 2. User's saved custom stages (becomes `inline`)

Look for `<name>.json` files in these locations (in order):

```
~/Desktop/new stage designs/           ← stage-builder skill's default save folder
~/Documents/Match Day/stages/         ← future canonical location (TBD)
~/Downloads/                          ← fallback for recently-downloaded shared stages
```

Match against the `name` field inside each JSON, not the filename. The filename is often `FC-NN_<slug>.json` but the `name` field is the human-readable label.

Snippet:

```python
import json
from pathlib import Path

candidates = []
for folder in [
    Path.home() / "Desktop/new stage designs",
    Path.home() / "Documents/Match Day/stages",
    Path.home() / "Downloads",
]:
    if not folder.is_dir():
        continue
    for p in folder.glob("*.json"):
        try:
            stage = json.loads(p.read_text())
            if stage.get("schemaVersion") != 2:
                continue  # Only Stage v2 JSONs
            if user_name.lower() in stage.get("name", "").lower():
                candidates.append((p, stage))
        except (json.JSONDecodeError, OSError):
            continue
```

If exactly one match: use it. If multiple matches: ask the user to disambiguate.

If matched, emit `{ "inline": <full Stage JSON> }`.

### 3. Ask the user for a path

If no resolution found, ask:

> *"I couldn't find a stage called 'Three Doors'. Do you have a path to the JSON file?"*

Accept any path the user provides; read the JSON, validate `schemaVersion == 2`, and inline it.

## Disambiguation

If the user's name partially matches both a bundled classifier and a custom stage (or multiple custom stages), present options:

> *"Found two stages matching 'Bang':
>  1. CM 99-62 'Bang and Clang' (bundled classifier)
>  2. ~/Desktop/new stage designs/FC-03_Bang-Drill.json
> Which one?"*

Always prefer the bundled classifier if the name is an exact match to a classifier name; require an explicit choice otherwise.

## Common nicknames

Map these to classifier codes when seen:

| Nickname            | Code        |
|---------------------|-------------|
| El Pres             | CM 99-11    |
| El Presidente       | CM 99-11    |
| Melody              | CM 99-08    |
| Quicky / Quicky II  | CM 99-13    |
| Hillbillton         | CM 99-28    |
| Fast and Furious    | CM 99-42    |
| Fast'n Furious      | CM 99-42    |
| Triple Play         | CM 99-53    |
| Bang and Clang      | CM 99-62    |

Add more here as new nicknames surface in user conversations.

## Stage v2 schema sanity check

Before inlining a custom stage, verify:
- `schemaVersion === 2` (silent-y-flip trap if missing)
- `markers.length >= 2`
- `props.length >= 1`
- `name` is non-empty

If any check fails, surface the problem to the user; don't silently inline a broken stage.

## Edge cases

- **Stage code with no spacing variations**: accept `cm99-08`, `CM-99-08`, `Cm 99 08` — normalize to canonical `CM 99-08` before matching.
- **Custom stage with the same name as a classifier**: prefer the bundled classifier unless the user explicitly says "my Melody Line" or "my version of Melody Line".
- **Stage referenced by file path** (e.g., user pastes `~/Desktop/cool-stage.json`): skip the name search, read directly, validate, inline.
