Skip to content

feat(runbooks): scenario-doc markdown render + staged per-phase activation#62

Open
msitarzewski wants to merge 1 commit into
mainfrom
feat/runbooks-doc-render-staged
Open

feat(runbooks): scenario-doc markdown render + staged per-phase activation#62
msitarzewski wants to merge 1 commit into
mainfrom
feat/runbooks-doc-render-staged

Conversation

@msitarzewski

Copy link
Copy Markdown
Owner

Summary

The two remaining Runbooks fast-follows, both reusing existing machinery.

1. Full scenario-doc markdown render

  • runbook_doc(slug) command resolves the runbook's manifest doc pointer within the active catalog and returns its markdown. The pointer is untrusted (a synced clone can be anything on disk): it must be a relative .md path with no .. escape, resolved strictly under the catalog root. Absent doc → empty string, not an error.
  • Extended the shared deterministic renderMarkdown (util/markdown.ts) with GFM pipe tables + blockquotes — the scenario docs lean on both (the roster is a table, the header a blockquote). Persona bodies benefit too. All text is still HTML-escaped before any tag is emitted, so {@html} stays safe.
  • Runbooks.svelte lazy-loads the doc behind a "Show scenario doc" toggle, rendering through that renderer; memoised per slug in the store.

2. Staged per-phase activation

Each roster group already carries its activation window (always / week 3+ / as needed). Added a per-group copy button that emits an activation prompt for just that phase's team — so you bring each group in when its window arrives instead of spinning up the whole roster at once.

Verification

  • Backend: new runbook_doc_path_guard_rejects_escapes (traversal / absolute / wrong-ext / empty all refused). cargo test corpus::34 passed. Lib compiles with the command registered.
  • Renderer: rendered a real catalog scenario doc through renderMarkdown — 6 tables, 1 blockquote, 14 headings, fenced code blocks — and confirmed the styled output visually (screenshot below).
  • Frontend: npm run check → 0 errors; npm run build clean.

New en-only strings (runbooks.phase* / showScenario / …) fall back to English in other locales per the established i18n pattern — queued for the next localization pass.

Note

Touches the same corpus/mod.rs test module as #61 (the #51 vendor). If #61 merges first I'll rebase this on top to resolve the adjacent-test insert.

🤖 Generated with Claude Code

…ation

Two follow-ups from the Runbooks MVP, both reusing existing machinery.

Scenario doc render:
- New `runbook_doc(slug)` command resolves the runbook's manifest `doc`
  pointer within the active catalog and returns its markdown. The pointer is
  treated as untrusted (a synced clone can be anything): it must be a
  relative `.md` path with no `..` escape, resolved strictly under the
  catalog root. Absent doc → empty string, not an error.
- Extend the shared, deterministic `renderMarkdown` (util/markdown.ts) with
  GFM pipe tables + blockquotes — the scenario docs lean on both (the roster
  is a table, the header a blockquote). Persona bodies benefit too. All text
  is still escaped before any tag is emitted, so `{@html}` stays safe.
- Runbooks.svelte lazy-loads the doc on a "Show scenario doc" toggle and
  renders it through that renderer, memoised per slug in the store.

Staged per-phase activation:
- Each roster group already carries its activation window (always / week 3+ /
  as needed). Add a per-group copy button that emits an activation prompt for
  just that phase's team, so you bring each group in when its window arrives
  instead of spinning up the whole roster at once.

Tests: runbook_doc_path_guard_rejects_escapes (traversal/absolute/ext/empty
all refused). cargo test corpus:: green; npm run check clean; build clean.
Rendered a real catalog scenario doc through the renderer to confirm tables,
blockquotes, headings, and code blocks all display correctly.

New en-only strings (runbooks.phase*/showScenario/...) fall back to English
in other locales per the established i18n pattern.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WdX6PvnCfRgYD11yVpXVor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant