Skip to main content

Living Docs Widget

mu-living-docs is a Lit custom element that renders a generated living document for a workflow version. Each section of the document corresponds to one rule node (DecisionNarrative) and presents its BA-readable prose, inputs, outputs, and a trace-jump button that links into the traceability matrix.

The component is read-only by design for the current release (read-only defaults to true).

Package

@muonroi/ui-engine-rule-components

Register all custom elements before using the component:

import { MRegisterRuleComponents } from "@muonroi/ui-engine-rule-components";
MRegisterRuleComponents();

Attributes

AttributeTypeDefaultRequiredDescription
api-base-urlstring""No*Base URL for the Living Docs read API. Required unless doc-json is provided.
tenant-idstring""NoActive tenant ID for API scoping.
workflowstring""No*Workflow identifier. Required unless doc-json is provided.
versionnumber0No*Rule version number. Required unless doc-json is provided.
doc-jsonstring""NoPre-fetched LivingDocModel as a JSON string. When set, bypasses the API call entirely.
read-onlybooleantrueNoAlways true for this release. Authoring mode is not yet available.

* Required when doc-json is not provided.

The component auto-loads on connectedCallback when api-base-url, workflow, and version are all set and doc-json is not provided. Setting doc-json at any time parses and renders the document immediately without a network call.

Event

living-docs-node-trace-requested

Dispatched when the user clicks the trace button on a rule section.

PropertyValue
bubblestrue
composedtrue
detail{ nodeId: string }

Wire this event to mu-traceability-matrix's filter-rule attribute to jump to the specific node in the matrix. See Traceability Matrix Widget for a wiring example.

Security

logicProse content is rendered via Lit's standard text interpolation — it is auto-escaped and never passed to unsafeHTML. This prevents XSS even if a rule's prose content contains angle brackets or script tags (source constraint T-04-04). Fetch failures set _error without silent catch (T-04-05).

API Endpoint

GET {api-base-url}/living-docs/{workflow}/{version}

Pass "active" as version to resolve the currently active version.

Response type: LivingDocModel

interface LivingDocModel {
workflow: string;
version: number;
tenantId: string;
generatedAt: string; // ISO 8601
generatedFromVersionHash: string; // SHA-256 provenance hash
sections: DecisionNarrative[];
factDictionary: FactRef[];
coverage: Coverage;
}

interface DecisionNarrative {
nodeId: string;
title: string;
inputs: FactRef[];
outputs: FactRef[];
logicProse: string; // BA-readable prose, no raw FEEL
sourceKind: string; // "feel" | "decision-table" | "nrules" | etc.
}

interface Coverage {
unitTestLinkedCount: number;
dryRunExampleCount: number;
noCoverageCount: number;
totalNodes: number;
}

React Wrapper

MuLivingDocsReact is the @lit/react-wrapped version, exported from @muonroi/ui-engine-react.

Event mapping:

React propDOM event
onNodeTraceRequestedliving-docs-node-trace-requested

Usage

Web Component

<script type="module">
import { MRegisterRuleComponents } from "@muonroi/ui-engine-rule-components";
MRegisterRuleComponents();
</script>

<!-- Fetch from API -->
<mu-living-docs
api-base-url="https://api.example.com/api/v1"
tenant-id="tenant-abc"
workflow="loan-approval"
version="5"
></mu-living-docs>

<!-- Or pass pre-fetched JSON to bypass the API -->
<mu-living-docs
doc-json='{"workflow":"loan-approval","version":5,...}'
></mu-living-docs>

<script>
document.querySelector("mu-living-docs").addEventListener(
"living-docs-node-trace-requested",
(e) => {
const matrix = document.querySelector("mu-traceability-matrix");
matrix.setAttribute("filter-rule", e.detail.nodeId);
}
);
</script>

React

import { useState } from "react";
import { MuLivingDocsReact, MuTraceabilityMatrixReact } from "@muonroi/ui-engine-react";

export function DocsWithMatrix() {
const [filterRule, setFilterRule] = useState("");

return (
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
<MuLivingDocsReact
api-base-url="https://api.example.com/api/v1"
tenant-id="tenant-abc"
workflow="loan-approval"
version={5}
onNodeTraceRequested={(e) => setFilterRule(e.detail.nodeId)}
/>
<MuTraceabilityMatrixReact
api-base-url="https://api.example.com/api/v1"
tenant-id="tenant-abc"
workflow="loan-approval"
version={5}
filter-rule={filterRule}
/>
</div>
);
}

States

StateDisplay
LoadingLoading indicator while the API call is in flight
ErrorError message if the fetch fails or doc-json cannot be parsed
EmptyNo sections rendered if sections array is empty
PopulatedOne prose block per DecisionNarrative in sections order

See Also