"Site" is the picker-facing concept (Scioto Historical's own branding
+ its tours), separate from "story" (a single tour's content) --
deliberately not called "provider", which already means something
else in this ecosystem (dc/smith/euro-style data providers). Reads
md's norm/site.json (written alongside story.jsonl by
CuratescapeProvider::storyNormalize()) the same way StoryFinder reads
story.jsonl -- no new entity, no persistence, same "small json blob"
shape.
StoryFinder::findForDataset() added so /sites/{code}/stories can scope
to just one site's dataset instead of scanning every known dataset --
the "pick a site, see its tours" flow, not a flat merge of everything.
Verified live against zm + md's real Scioto Historical data:
/stories/sites lists 1 site, /stories/sites/scioto returns its full
skin metadata (label/contact/license/storyIds), /stories/sites/scioto/stories
returns all 11 of its tours.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>