Rendering engine for the Entangled v1.0 protocol. It lowers an already-verified content or transaction document into a toolkit-neutral scene IR: a flat list of scene nodes that a concrete rendering layer (a future chrome/GUI crate) materializes into pixels.
The protocol specification lives at github.com/samjanny/entangled.
Documents are produced and verified by entangled-core.
entangled-core entangled-engine chrome/GUI crate (future)
ContentDocument -> Scene (toolkit-neutral) -> pixels, widget toolkit,
(verified) pure function events, image fetch/state
The engine walks a verified document's blocks and produces a Scene: one
SceneNode per block, with inline content resolved into styled runs, link
targets classified by kind, and images carried by reference. Its value is the
normalization a renderer wants:
- inline
marks(bold/italic/code/strikethrough) are flattened from the protocol's mark vector into aTextStyleof independent boolean flags; - link targets are classified into a
LinkClass(SameSite/Entangled/Carrier/Citation) so the rendering layer can apply the section 03 / section 10 navigation policy, while the target data is carried verbatim in the protocol's own validated types; - the semantic attributes the protocol defines (heading level, list ordering, feedback/note variant) are carried through; the visual treatment of each is left to the rendering layer, as section 03 specifies.
The engine consumes the typed output of entangled-core - a ContentDocument
or TransactionDocument that has passed the full validation pipeline and whose
newtypes already carry every protocol invariant (heading levels 1..=6, well-formed
slugs and paths, enforced inline byte budgets, duplicate-free marks).
Because the input is already valid, the lowering is total and infallible:
Scene::from_content and Scene::from_transaction return a Scene directly,
never a Result. The engine re-validates nothing; it only re-shapes.
Like the Rust reference verifier (entangled-core), this crate draws a
deliberate boundary. It covers the transformation from a verified document to a
scene IR and nothing else.
Out of scope for this crate (left to the embedding chrome/GUI layer):
- parsing, schema validation, and signature verification (done by
entangled-corebefore a document reaches this crate); - any I/O: image resource fetching, network, filesystem, the clock. The engine
emits an
ImageRefdescribing the image a document binds (path, hash, media type, dimensions, alt/caption) but never fetches it; fetch, hash verification, decoding, and load/failed state belong to the layer above, per section 03; - chrome: publisher trust state, canary state, the PIP, and security warnings;
- pixel-level layout, font shaping, and any widget toolkit. The IR is abstract;
- user input, events, navigation, and link-follow confirmation. The engine classifies a link target so the layer above can apply navigation policy, but applies none itself.
use entangled_engine::Scene;
// `doc` is a verified ContentDocument obtained from entangled-core.
fn render(doc: &entangled_core::types::ContentDocument) {
let scene = Scene::from_content(doc);
for node in &scene.nodes {
// hand each node to your rendering layer
let _ = node;
}
}serde(off by default): derivesSerializeon the scene IR types, used for golden/snapshot testing and consumable by a future web rendering backend. The IR otherwise depends only onentangled-core.text(off by default): a headless plain-text renderer (text::render) that turns aSceneinto deterministic structured text. It is the first real consumer of the IR - it validates the IR shape and serves as a correctness oracle for richer renderers (TUI, GUI, web). It is pure: no I/O, no toolkit.
cargo build
cargo test
cargo test --all-features
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --checkDual-licensed under either of:
- MIT License
- Apache License, Version 2.0
at your option.