Visualization
The visualize module generates Mermaid diagrams and HTML exports for pipeline state.
Related Chapters
- Pipeline - State definitions
- Layout - Position calculations
- Render - Screen coordinate mapping
- Slint Viz - Slint integration
- Match Visualization Plan - future multi-arm branch semantics
- Desktop Agent and Office Playbook Surface - MCPB, OneNote, SharePoint, and local simulation surface
PipelineGraph
fn workflow_toml() -> pipeline_graph
fn pipeline_state() -> pipeline_graph
fn pipeline_graph() -> to_mermaid
fn pipeline_graph() -> to_html
fn to_mermaid() -> mermaid_svg
fn to_html() -> html_export
flowchart TD
workflow_toml["workflow_toml"]
pipeline_graph["pipeline_graph"]
pipeline_state["pipeline_state"]
to_mermaid["to_mermaid"]
to_html["to_html"]
mermaid_svg["mermaid_svg"]
html_export["html_export"]
workflow_toml --> pipeline_graph
pipeline_state --> pipeline_graph
pipeline_graph --> to_mermaid
pipeline_graph --> to_html
to_mermaid --> mermaid_svg
to_html --> html_export
#![allow(unused)]
fn main() {
pub struct PipelineGraph {
pub nodes: HashMap<String, NodeVisualState>,
pub edges: Vec<EdgeVisual>,
pub current_state: String,
pub accumulated_confidence: f32,
}
}
NodeVisualState
Visual states for pipeline nodes:
- Idle: Waiting, not entered
- Active: Currently executing
- Success: Completed successfully
- Warning: Recoverable issue
- Error: Unrecoverable issue
- Review: Awaiting human review
Mermaid Generation
#![allow(unused)]
fn main() {
let mermaid = graph.to_mermaid();
// Generates stateDiagram-v2
}
Live Rhai Editor
The rendered book now upgrades generated Rhai diagram blocks into a local editor + preview surface. Use just docserve, open the book in a browser, edit a supported ```rhai block, and click Regenerate to redraw the chart without changing the source markdown.
The live editor uses the same narrow diagram DSL as the mdBook preprocessor:
fn source() -> targetif expression -> targetmatch expr => Arm -> target
The preview surface exposes a two-position view slider:
isometric-3drenders an animated SVG scene with deterministic layered placement, so inserting a node causes nearby steps to visibly reflow instead of snapping in placemermaid-2dkeeps the canonical Mermaid flowchart for the same parsed graph
Diagnostics now surface line-level parse feedback:
- malformed DSL lines are marked as errors
- ignored non-DSL lines are marked as informational notes
- Mermaid failures include a concrete fallback hint to switch to the isometric view
Node visuals use an internal SVG icon library keyed by inferred workflow role (ingest, validate, classify, review, reconcile, commit, decision), and each node carries an autogenerated glTF data URI when no explicit model is supplied. The docs renderer still draws the isometric scene in SVG so it works inside mdBook without a separate WebGL runtime.
Model-Assisted Rule Mutation
Each live editor also includes a Rhai mutation prompt panel. Type the desired workflow change, click Prepare Model Prompt, and paste that prompt into the configured local or OpenAI-compatible model. The prompt is constrained to the supported documentation DSL and asks the model to return a replacement block plus a short explanation.
The checked-in playground does not make browser-side model calls. Apply Example Draft demonstrates the expected interaction by applying a deterministic Phi-family example mutation to the editor, then re-rendering the same Mermaid and isometric views. The default example target is phi-4-mini-reasoning; if a Phi-5 endpoint is configured later, the same prompt contract can be sent through the Slint host chat window or another supervised model bridge without changing the DSL.
Example prompt request:
Add a medium-confidence review path and keep workbook commit behind review or high confidence.
Example model-shaped mutation:
fn classify_rows() -> score_confidence
if confidence > 0.85 -> commit_workbook
if confidence > 0.60 -> review_flag
if confidence <= 0.60 -> escalate_operator
fn review_flag() -> commit_workbook
flowchart TD
classify_rows["classify_rows"]
score_confidence["score_confidence"]
review_flag["review_flag"]
commit_workbook["commit_workbook"]
confidence_gt_0_85{"confidence > 0.85"}
confidence_gt_0_6{"confidence > 0.6"}
confidence____0_60{"confidence <= 0.60"}
escalate_operator["escalate_operator"]
classify_rows --> score_confidence
review_flag --> commit_workbook
confidence_gt_0_85 -->|"true"|commit_workbook
confidence_gt_0_85 -->|"false"|confidence_gt_0_6
confidence_gt_0_6 -->|"true"|review_flag
confidence____0_60 -->|"true"|escalate_operator
Sample Gallery
Use the examples below as copy-paste seeds in the live editor. Each sample is deliberately small enough to make view changes obvious.
Sample: Ledger Ingest Happy Path
fn ingest_pdf() -> detect_shape
fn detect_shape() -> validate_rows
fn validate_rows() -> classify_rows
fn classify_rows() -> reconcile_rows
fn reconcile_rows() -> commit_workbook
flowchart TD
ingest_pdf["ingest_pdf"]
detect_shape["detect_shape"]
validate_rows["validate_rows"]
classify_rows["classify_rows"]
reconcile_rows["reconcile_rows"]
commit_workbook["commit_workbook"]
ingest_pdf --> detect_shape
detect_shape --> validate_rows
validate_rows --> classify_rows
classify_rows --> reconcile_rows
reconcile_rows --> commit_workbook
Expected view behavior:
mermaid-2dshould read as a simple left-to-right pipelineisometric-3dshould keep every stage on one main spine with no lane fan-out
Sample: Confidence Gate with Review Path
fn classify_rows() -> score_confidence
if confidence > 0.85 -> commit_workbook
if confidence > 0.60 -> review_flag
if confidence <= 0.60 -> escalate_operator
fn review_flag() -> commit_workbook
flowchart TD
classify_rows["classify_rows"]
score_confidence["score_confidence"]
review_flag["review_flag"]
commit_workbook["commit_workbook"]
confidence_gt_0_85{"confidence > 0.85"}
confidence_gt_0_6{"confidence > 0.6"}
confidence____0_60{"confidence <= 0.60"}
escalate_operator["escalate_operator"]
classify_rows --> score_confidence
review_flag --> commit_workbook
confidence_gt_0_85 -->|"true"|commit_workbook
confidence_gt_0_85 -->|"false"|confidence_gt_0_6
confidence_gt_0_6 -->|"true"|review_flag
confidence____0_60 -->|"true"|escalate_operator
Expected view behavior:
- Mermaid should show three labeled outgoing edges from the confidence checks
- the isometric view should place
review_flagandescalate_operatoron separate side lanes - inserting a new medium-confidence branch should animate the lane spread rather than replacing the whole scene
Sample: Match-Style Disposition Routing
This now uses the dedicated match-arm DSL.
fn verify_result() -> match_result_disposition
match result.disposition => Disposition::Unrecoverable -> halt_pipeline
match result.disposition => Disposition::Recoverable -> repair_and_retry
match result.disposition => Disposition::Advisory -> record_note
fn repair_and_retry() -> requeue_validation
flowchart TD
verify_result["verify_result"]
match_result_disposition["match_result_disposition"]
repair_and_retry["repair_and_retry"]
requeue_validation["requeue_validation"]
halt_pipeline["halt_pipeline"]
record_note["record_note"]
verify_result --> match_result_disposition
repair_and_retry --> requeue_validation
match_result_disposition -->|"Disposition::Unrecoverable"|halt_pipeline
match_result_disposition -->|"Disposition::Recoverable"|repair_and_retry
match_result_disposition -->|"Disposition::Advisory"|record_note
Use this sample when comparing the current live rendering with the intended placement and reflow rules in Match Visualization Plan.
Executable Rust Example
#![allow(unused)]
fn main() {
use ledger_core::workflow::examples::ledger_ingest;
let workflow = ledger_ingest();
workflow.validate().expect("example workflow should be valid");
let mermaid = workflow.to_mermaid();
let rhai = workflow.to_rhai();
assert!(mermaid.contains("Ingested --> Validating"));
assert!(rhai.contains("next_state"));
}
HTML Export
#![allow(unused)]
fn main() {
let html = to_html(&graph);
// Returns complete HTML with Mermaid.js
}
Office Playbook Export
The desktop agent treats diagrams as versioned playbook artifacts that can be inserted into OneNote/Office or rendered in SharePoint. A diagram export is therefore more than a screenshot: it must carry a typed playbook model, render metadata, simulation profile, and evidence refs.
Minimum formats:
| Format | Use |
|---|---|
| Mermaid | Source-level editable diagram and review diff. |
| SVG | Preferred high-fidelity Office/SharePoint visual artifact where supported. |
| PNG | Compatibility fallback for Office clients that do not preserve SVG behavior. |
| HTML | Interactive playbook renderer for local desktop and SharePoint-hosted views. |
| JSON | Canonical playbook model with typed nodes, edges, gates, b00t capability refs, ledgrrr evidence refs, and simulation state. |
Refresh semantics:
- A refresh creates a new artifact version.
- The previous published artifact remains addressable.
- The evidence graph records source input, model/runtime profile, render hash, and approval state.
- OneNote/Office and SharePoint views render the artifact; ledgrrr remains the owner of source truth and provenance.
LayoutSolver
Kasuari-backed constraint solver for node positioning:
#![allow(unused)]
fn main() {
pub struct LayoutSolver;
pub fn generate_layout(&self, graph: &PipelineGraph) -> HashMap<String, (f32, f32)>;
}