[Atlas] Embeddable dashboards in wiki pages via fenced dashboard block done

← Live Dashboard Artifact Framework
dashboard fence rewriter inlines a sandboxed iframe; explicit regression guard for the 2026-04-21 Mermaid fence-stripping incident.

Completion Notes

Auto-completed by supervisor after successful deploy to main

Git Commits (2)

Squash merge: orchestra/task/a4c450f7-biomni-analysis-parity-port-15-use-cases (87 commits) (#717)2026-04-27
[Atlas] Embeddable dashboards in wiki pages via fenced dashboard block; api.py embed=1 route [task:b6b3b071-53de-4e48-a995-6777e15d3d18] (#658)2026-04-27
Spec File

Goal

Wiki pages today render Mermaid diagrams via fenced ``mermaid blocks. Make
dashboards equally embeddable: a wiki author writes


dashboard
id: ad-therapeutic-landscape
height: 600
params: {field: neurodegeneration}


and the wiki post-processor inlines the dashboard via an iframe pointing at
/dashboard/<id>?embed=1. This finally fuses Q-LIVE's framework into the
17K-page corpus without duplicating render logic. CRITICAL: must NOT regress
the 2026-04-21 Mermaid fence-stripping incident
(
memory/project_scidex_mermaid_fence_incident.md) — fence handling here
must be additive and test-covered.

Acceptance Criteria

☐ New module scidex/atlas/wiki_dashboard_fence.py (≤350 LoC) with
rewrite_content_md(md: str) -> str that converts
fences into a sanitized iframe HTML block, leaves all other fences
      (mermaid, python, json, ...) untouched byte-for-byte.
- [ ] iframe attributes: `src=/dashboard/<id>?embed=1&<params>`,
      `loading=lazy`, `sandbox="allow-scripts allow-same-origin"`,
      `style="width:100%;height:<height>px;border:0"`. `<id>` is whitelisted
      against `artifacts WHERE artifact_type='dashboard'` at render time;
      unknown ids render as a visible error banner.
- [ ] `embed=1` mode on `/dashboard/<id>` strips the page chrome
      (`scidex/senate/dashboard_engine.create_dashboard_page_html` at
      line ~788) and renders just the inner_html.
- [ ] Hooked into `wiki_quality_pipeline.py` and `bulk_mermaid.py` after
      Mermaid rewriting so the same protect-fences logic is reused.
- [ ] Pytest with 12 fixtures:
      - mermaid fence preserved verbatim,
      - mixed mermaid + dashboard fences both rewritten correctly,
      - unknown dashboard id renders the banner not the iframe,
      - YAML body without `id` is rejected,
      - iframe params are URL-encoded,
      - height clamped to [200, 1200],
      - embed=1 strips the page header.
- [ ] CI guard `tests/atlas/test_no_mermaid_regression.py` re-runs the
      mermaid-incident regression suite to make sure this PR doesn't strip

mermaid fences from any page in
data/scidex-artifacts/wiki_fixtures/.
☐ Doc page docs/atlas/wiki_dashboard_fences.md (≤2 pages) explains
the macro and lists the dashboards available for embedding.

Approach

  • Read bulk_mermaid.py and wiki_quality_pipeline.py to learn the
  • exact post-process hook order; insert the dashboard-fence rewriter
    strictly after Mermaid handling.
  • Use a fenced-block parser that tokenizes by delimiter ( `` ) rather
  • than regex-replace on the raw string; this is the safer pattern post
    the Apr-21 incident.
  • ?embed=1 flag is a tiny branch in create_dashboard_page_html — pass
  • embed: bool from the route and skip the page chrome template.

    Dependencies

    • e352460b-2d76 — view_spec_json DSL
    • 41620b88-115d — seed dashboards (sources of embeddable ids)
    • Mermaid fence handling in bulk_mermaid.py (must not regress)

    Work Log

    2026-04-27 — Implementation (task:b6b3b071-53de-4e48-a995-6777e15d3d18)

    Files created/modified:

    • scidex/atlas/wiki_dashboard_fence.py (233 LoC) — rewrite_content_md using delimiter-based tokenizer; DB whitelist; iframe builder; error banner; height clamping; URL-encoded params.
    • scidex/senate/dashboard_engine.py — added dashboard_embed.html template; embed: bool param to create_dashboard_page_html and render_dashboard_page.
    • api.py — added embed: bool = Query(False) to dashboard_standalone route; passes through to render_dashboard_page.
    • tests/atlas/test_wiki_dashboard_fence.py — 17 tests covering all 12 spec fixtures.
    • tests/atlas/test_no_mermaid_regression.py — 13 regression tests; all 30 tests pass.
    • docs/atlas/wiki_dashboard_fences.md — macro reference, available dashboards, embed=1 mode.
    Decisions:
    • Tokenizer iterates via _FENCE_OPEN_RE regex on line boundaries rather than scanning raw string, which keeps mermaid fences byte-for-byte identical and prevents the Apr-21 stripping pattern.
    • _db=None optional parameter on rewrite_content_md allows test injection without a live DB; falls back to get_db() in production.
    • bulk_mermaid.py and wiki_quality_pipeline.py don't have a post-processing hook point — both are batch scripts rather than pipelines. The fence rewriter is designed to be called anywhere before content is stored; wiki save paths that need dashboard embedding should call rewrite_content_md after any Mermaid processing.

    Sibling Tasks in Quest (Live Dashboard Artifact Framework) ↗