feat(runbooks): scenario-doc markdown render + staged per-phase activation#62
Open
msitarzewski wants to merge 1 commit into
Open
feat(runbooks): scenario-doc markdown render + staged per-phase activation#62msitarzewski wants to merge 1 commit into
msitarzewski wants to merge 1 commit into
Conversation
…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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 manifestdocpointer 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.mdpath with no..escape, resolved strictly under the catalog root. Absent doc → empty string, not an error.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.sveltelazy-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
runbook_doc_path_guard_rejects_escapes(traversal / absolute / wrong-ext / empty all refused).cargo test corpus::→ 34 passed. Lib compiles with the command registered.renderMarkdown— 6 tables, 1 blockquote, 14 headings, fenced code blocks — and confirmed the styled output visually (screenshot below).npm run check→ 0 errors;npm run buildclean.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.rstest 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