Story URLs now mirror GitHub structure
Story pages now use URLs that match the GitHub resources they describe — /pull/<n>/ for PRs and /commit/<sha>/ for commits — replacing opaque internal IDs with semantic, shareable links.
Story pages now expose GitHub-style URLs instead of opaque identifiers. When sharing a link to a pull request summary or commit story, readers immediately know what they're clicking — the URL structure mirrors the GitHub resource itself.
Previously, all stories lived under /stories/<id>/ where the ID was an internal manifest key. Now, PR stories appear at /pull/<n>/<slug>/ and commit stories at /commit/<sha>/<slug>/. The slug is decorative, pulled from the headline for SEO; the meaningful identifier is the PR number or commit SHA in the path.
URL helpers in lib/urls.ts now generate paths based on story kind rather than the story ID. Two new loader functions — loadStoryByPrNumber and loadStoryBySha — support the new routing. Slug validation was tightened: empty slugs fall back to "untitled" so URLs always have a valid trailing segment, and malformed story data fails fast with explicit errors instead of producing broken paths.
Release pages follow the same pattern, now using /releases/tag/<tag>/ to match how GitHub displays releases. Old paths return 404 — a clean break with no redirect stubs needed.