security(apps): route marked.parse through DOMPurify across apps tree master
Closes the nine raw `marked.parse(...) → innerHTML` sites in the apps tree by routing all markdown rendering through a canonical `renderMarkdown(raw)` helper that wraps marked in DOMPurify.sanitize. Promotes DOMPurify to a shell-level script include in `convey/templates/app.html` so every app inherits it, and retires two home-grown sanitizers whose threat models were narrower than DOMPurify's. Closed sites: - apps/home/workspace.html (4 sites: narrative init, briefing sections, skill detail, narrative refresh) - apps/activities/_day.html (activity markdown output) - apps/import/workspace.html (guided-flow step content) - apps/import/_detail.html (imported content preview) - apps/sol/workspace.html (2 sites: run output pane, finish-event result) Retired: - apps/sol/workspace.html::sanitizeHtml (DOMParser allowlist) - apps/import/_detail.html::sanitizeMarkdown (regex pre-filter) Normalized apps/transcripts/workspace.html::renderMarkdown to the canonical shape (which adds { breaks: true, gfm: true }, matching the options every other call site already passed). Removed now-redundant per-app DOMPurify includes in transcripts and reflections, and cleaned adjacent dead code in apps/import/_detail.html (local marked include, stray marked.setOptions, unused markedRenderer). Extends the pattern shipped in 5382b346 (transcripts) and the reflections hardening to the rest of the apps tree. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>