feat: shareable issue permalinks (/i/{shortID}) — issue-as-resource master
Deep-linking the hypermedia way: the ISSUE is the resource and gets a canonical URL; the session stays the resource, so the URL is never mirrored/rewritten as you navigate. - GET /i/{shortID}: SSR-renders the app focused on the issue (no flash) via a shared renderPage(initial, seedSelect) extracted from handleIndex; 404 for missing/bad ids (a real resource 404). - The page's data-init seeds the live session before opening the stream (@post('/cmd/select?id=N').then(() => @get('/stream'))), so the projection agrees with first paint — no reconcile flash, race-free. - The detail's #N is a real <a href="/i/N"> permalink that tracks the open issue (pull on demand); navigating within the session does not change the URL. Verified: /i/1246 opens the issue with the stream live; missing/bad ids 404; opening another issue repoints the permalink to /i/1217 while the URL stays /i/1246. Refs tasks/deep-linkable-urls.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>