Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

l3dg3rr is a local-first personal financial document intelligence system focused on retroactive U.S. expat tax preparation from raw PDF statements.

Architecture

The system implements a 6-layer visualization stack:

LayerModuleDescription
0graph.rsNodeData, EdgeData, pipeline node/edge vectors
1layout.rsForceLayout with Fruchterman-Reingold solver
2layout.rsIsometric projection (iso_project)
3render.rsGraphRenderer for screen coordinates
4slint_viz.rsSlintGraphView with thread-safe layout
5host-window.rsGraphView Slint component

Source Documentation

This book is auto-generated from Rustdoc comments in the source code.

cargo doc --workspace --no-deps
mdbook build

Graph Data Model

The graph module provides the data structures for the pipeline visualization.

NodeData

#![allow(unused)]
fn main() {
pub struct NodeData {
    pub label: String,
    pub color: [f32; 3],
    pub mass: f32,
}
}
  • label: Human-readable name for the node (e.g., “Ingested”, “Validating”)
  • color: RGB values as floats [0-1] for visualization
  • mass: Relative size/weight for force-directed layout

EdgeData

#![allow(unused)]
fn main() {
pub struct EdgeData {
    pub weight: f32,
}
}
  • weight: Edge strength for layout calculations

Functions

create_pipeline_nodes

Returns the standard pipeline node definitions:

  • Ingested
  • Validating
  • Classifying
  • Reconciling
  • Committed

create_pipeline_edges

Returns the standard pipeline connections:

  • Ingested → Validating
  • Validating → Classifying
  • Classifying → Reconciling
  • Reconciling → Committed

Force Layout

The layout module implements force-directed graph layout using a custom Fruchterman-Reingold algorithm.

ForceLayout

#![allow(unused)]
fn main() {
pub struct ForceLayout {
    positions: HashMap<usize, Vec3>,
    velocities: HashMap<usize, Vec3>,
}
}

Methods

new()

Creates an empty force layout.

for_pipeline()

Creates a force layout initialized with the standard pipeline nodes arranged in a circle.

tick()

Runs one iteration of the force-directed layout algorithm, updating node positions based on:

  • Repulsion between all nodes
  • Attraction along edges
  • Center gravity to keep the graph bounded

position(node_idx: usize) -> Option

Returns the 3D position of a node by index.

all_positions() -> &HashMap<usize, Vec3>

Returns all node positions.

Usage

#![allow(unused)]
fn main() {
let mut layout = ForceLayout::for_pipeline();
for _ in 0..100 {
    layout.tick();
}
for (idx, pos) in layout.all_positions() {
    println!("Node {}: {:?}", idx, pos);
}
}

Isometric Projection

The isometric projection converts 3D force-directed positions to 2D screen coordinates.

iso_project

#![allow(unused)]
fn main() {
pub fn iso_project(p: Vec3, scale: f32, origin: Vec2) -> Vec2
}

Parameters

  • p: 3D position from force layout (Vec3)
  • scale: Pixel scale factor (default: 32.0)
  • origin: Screen center point (Vec2)

Returns

2D screen coordinates (Vec2)

Formula

#![allow(unused)]
fn main() {
x = origin.x + (p.x - p.z) * scale * 0.866  // cos(30°)
y = origin.y + (p.x + p.z) * scale * 0.5 - p.y * scale
}

This produces a classic dimetric isometric view with 2:1 pixel ratio.

Usage

#![allow(unused)]
fn main() {
let screen_pos = iso_project(node_position, 32.0, Vec2::new(400.0, 300.0));
}

Renderer

The render module provides screen coordinate mapping for the visualization.

GraphRenderer

#![allow(unused)]
fn main() {
pub struct GraphRenderer {
    pub width: u32,
    pub height: u32,
    pub scale: f32,
    pub origin: Vec2,
}
}

Methods

new(width: u32, height: u32)

Creates a renderer with the specified canvas dimensions.

screen_position(x: f32, y: f32, z: f32) -> Vec2

Converts 3D coordinates to 2D screen position using isometric projection.

Usage

#![allow(unused)]
fn main() {
let renderer = GraphRenderer::new(800, 600);
let screen = renderer.screen_position(100.0, 0.0, 50.0);
}

Slint Visualization

The slint_viz module integrates the graph visualization with Slint UI framework.

SlintGraphView

#![allow(unused)]
fn main() {
pub struct SlintGraphView {
    pub renderer: GraphRenderer,
    pub layout: Arc<RwLock<ForceLayout>>,
}
}

Features

  • Thread-safe layout using Arc<RwLock<ForceLayout>>
  • Animation support via timer-driven tick updates
  • Real-time position updates for Slint binding

Methods

new(width: u32, height: u32)

Creates a new Slint-integrated graph view.

tick()

Advances the force layout by one iteration. Thread-safe.

screen_position(node_idx: usize) -> Option<(f32, f32)>

Returns the screen position for a node.

Integration

#![allow(unused)]
fn main() {
let view = SlintGraphView::new(800, 600);

// In animation loop:
view.tick();
let pos = view.screen_position(0);
}

Pipeline

The pipeline module implements a type-state pattern for the document processing workflow.

State Types

  • Ingested: Document has been parsed
  • Validating: Checking data integrity
  • Classifying: Categorizing transactions
  • Reconciling: Matching against external data
  • Committed: Finalized andauditable

Type-State Pattern

The pipeline uses Rust’s type system to enforce state transitions at compile time:

#![allow(unused)]
fn main() {
pub struct PipelineState<S> { /* ... */ }

impl PipelineState<Ingested> {
    pub fn validate(self) -> PipelineState<Validating> { ... }
}

impl PipelineState<Validating> {
    pub fn classify(self, category: String) -> PipelineState<Classified> { ... }
}
}

This ensures invalid state transitions are caught at compile time.

Statig Integration

The pipeline uses statig for hierarchical state machine (HSM) implementation with:

  • Superstates for grouping related states
  • State-local storage for context
  • Async-first design

Validation

The validation module provides the core type system for pipeline stage results.

Disposition

#![allow(unused)]
fn main() {
pub enum Disposition {
    Unrecoverable,  // Fatal error, cannot proceed
    Recoverable,    // Error that can be fixed
    Advisory,       // Warning or suggestion
}
}

Issue

#![allow(unused)]
fn main() {
pub struct Issue {
    pub disposition: Disposition,
    pub message: String,
    pub source: IssueSource,
}
}

MetaCtx

Metadata context that accumulates through pipeline stages:

#![allow(unused)]
fn main() {
pub struct MetaCtx {
    pub accumulated_confidence: f32,  // Compounded from all stages
    pub stage_history: Vec<StageResult>,
    // ...
}
}

Confidence compounds multiplicatively: next.confidence = current.confidence * stage.confidence

StageResult

Captures the outcome of a pipeline stage with issues and confidence score.

Legal Verification

The legal module provides tax rule verification across multiple jurisdictions.

Jurisdiction

Supported tax jurisdictions:

  • US: United States (Schedule C, Form 1040)
  • AU: Australia (GST, BAS)
  • UK: United Kingdom (VAT, CT)

LegalSolver

#![allow(unused)]
fn main() {
pub struct LegalSolver {
    jurisdiction: Jurisdiction,
    rules: Vec<TaxRule>,
}
}

TaxRule

#![allow(unused)]
fn main() {
pub struct TaxRule {
    pub id: String,
    pub jurisdiction: Jurisdiction,
    pub description: String,
    pub validator: fn(&Transaction) -> bool,
}
}

Verification

The solver checks transactions against jurisdiction-specific tax rules:

  • US: Schedule C business expense categorization
  • AU: GST Act s38-190 compliance
  • UK: VAT deductibility rules

Usage

#![allow(unused)]
fn main() {
let solver = LegalSolver::us();
let result = solver.verify(&transaction);
match result.disposition {
    Disposition::Unrecoverable => { /* fatal tax issue */ }
    Disposition::Recoverable => { /* fixable */ }
    Disposition::Advisory => { /* suggestion */ }
}
}

Constraints

The constraints module implements Kasuari-based data plausibility validation.

VendorConstraintSet

#![allow(unused)]
fn main() {
pub struct VendorConstraintSet {
    pub vendor: String,
    pub constraints: Vec<Constraint>,
}
}

Constraint Types

  • AmountRange: Valid transaction amount bounds
  • DateWindow: Expected date range for statements
  • DescriptionPattern: Regex pattern for valid descriptions
  • AccountFormat: Valid account number format

Kasuari Integration

The module uses Kasuari strengths for constraint evaluation:

  • Strong: Must pass for validation to succeed
  • Medium: Warning if violated
  • Weak: Advisory if violated

InvoiceConstraintSolver

#![allow(unused)]
fn main() {
pub struct InvoiceConstraintSolver {
    // ...
}
}

Solves constraints for invoice data with multi-pass validation.

Verification

The verify module implements multi-model verification for quality assurance.

Multi-Model Verification

The system uses a two-model approach:

  1. Proposer: Primary model generates the classification/decision
  2. Reviewer: Second model reviews and validates the proposal

Verifier

#![allow(unused)]
fn main() {
pub struct Verifier {
    proposer: ModelClient,
    reviewer: ModelClient,
}
}

Process

  1. Proposer generates a candidate classification
  2. Reviewer evaluates the candidate against constraints
  3. If reviewer rejects, human review is flagged
  4. Confidence score reflects agreement between models

Usage

#![allow(unused)]
fn main() {
let verifier = Verifier::new(model_a, model_b);
let result = verifier.verify(&transaction, Proposal::Classify);
}

Workflow

The workflow module provides a TOML-based DSL for defining pipeline stages and transitions.

WorkflowToml

#![allow(unused)]
fn main() {
pub struct WorkflowToml {
    pub version: String,
    pub state: Vec<StateDef>,
    pub transitions: Vec<TransitionDef>,
}
}

StateDef

#![allow(unused)]
fn main() {
pub struct StateDef {
    pub id: String,
    pub description: String,
    pub verbs: Vec<VerbDef>,
}
}

TransitionDef

#![allow(unused)]
fn main() {
pub struct TransitionDef {
    pub from: String,
    pub to: String,
    pub event: String,
    pub guard: Option<String>,
}
}

Compilation

The workflow DSL compiles to:

  • Mermaid: Visual diagram generation
  • Rhai: Runtime execution FSM
  • Rust enum: Compile-time type safety

Example

[workflow]
version = "1.0"

[[state]]
id = "Ingested"
description = "Document parsed"

[[state]]
id = "Validating"
description = "Checking integrity"

[[transition]]
from = "Ingested"
to = "Validating"
event = "validate"

Visualization

The visualize module generates Mermaid diagrams and HTML exports for pipeline state.

PipelineGraph

#![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
}

HTML Export

#![allow(unused)]
fn main() {
let html = to_html(&graph);
// Returns complete HTML with Mermaid.js
}

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)>;
}