Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

facett-graphview/.nornir/elite-graph-engine.md

facett-graphview — Elite Graph Engine

Moving facett-graphview (+ facett-helix) from "D3 / Three.js algorithms ported to Rust" into an enterprise-grade graph engine. The nordisk domain is primarily structured directional dataflows — SCIP call graphs, skade lineage, ordning plan-DAGs, modgunn dep graphs, execution/pipeline DAGs — so the engine optimises for directed / layered / temporal graphs first, while the GPU force layout covers the general arbitrary-web case so nothing chokes.

Two curses to beat: the hairball (edge density) and layout perf at scale.

This branch (agent/graphview-elite) lands the foundation. Below is the endorsed plan (the "Gemini consult"), then exactly what landed, what spiked, and the roadmap for each technique, with the concrete approaches.


The plan (endorsed)

# Technique Curse it kills Status
1 GPU-compute layout — force-direction in a wgpu compute shader, weights+adjacency streamed from Arrow, positions iterate in VRAM layout perf at scale LANDED
2 Force-directed edge bundling (FDEB) — compatible edges attract into information highways the hairball LANDED
3 Topological semantic zoom — Louvain communities → meta-nodes that collapse/fracture by zoom both (legibility at scale) LANDED (level-1 Louvain)
4 Mental-map stability (helix) — anchor constraints bound per-step node travel; time→helix depth dynamic-graph churn LANDED

All four pure cores are deterministic (FC-7) and assert their results as DATA (positions / metrics / partition), not screenshots. The GPU paths self-skip without an adapter. Reused GPU stack: facett-core gpu::particles (boids compute + storage ping-pong + additive HDR bloom), facett-graph3d instanced emissive lane, facett-helix rubberband Catmull-Rom / elastic splines, injected-clock easing.


1. GPU-compute layout — LANDED (src/gpu_layout.rs, src/layout.wgsl)

Approach. A wgpu compute-shader n-body layout. The graph is held in CSR (GraphCsr { offsets, targets, weights }), which is the upload format — the three Vecs map 1:1 onto GPU storage buffers, streamed straight from an Arrow edge batch (GraphCsr::from_arrow, feature arrow: Int64 src/dst + an optional Float64 weight column). GpuLayout::new uploads the CSR + a deterministic golden-angle seed; iterate runs the cs_layout kernel entirely in VRAM (ping-pong src→dst, no per-step readback); read_positions copies the settled [f32;2] positions back as DATA.

The force model is Fruchterman-Reingold, velocity-integrated:

The all-pairs repulsion is the same O(n²) compute shape as the boids in facett_core::render::gpu::particles — same @workgroup_size(64), same storage ping-pong, same headless request_adapter probe. The CPU step_cpu/relax_cpu is the no-GPU fallback and the parity reference the WGSL mirrors line-for-line.

Tests (DATA): CSR symmetry/dedup, deterministic seed + bit-identical step, energy-decay convergence (the metric drops an order of magnitude), the analytic single-edge equilibrium d=(1+√3)/2, mass-weighted motion, Arrow ingestion, and a GPU↔CPU parity proof (gpu_layout_matches_cpu_reference, self-skips without a device — passes on this host).

Roadmap (the 100k case). The O(n²) repulsion is the foundation. To reach 10k–100k nodes in real time:

2. Force-directed edge bundling — LANDED (src/fdeb.rs)

Approach. Holten & van Wijk FDEB. Each edge becomes a flexible wire subdivided into control points; compatibility Ca·Cs·Cp (angle · scale · position) is precomputed and pruned, then a force loop runs electrostatic attraction between compatible wires' matching points (cohesion → bundles) balanced by a spring keeping each wire's own points evenly spaced (the rubberband). Compatible edges collapse into shared "information highways" that split near the endpoints. The force is the same boids/n-body shape as #1 — cohesion to compatible neighbours.

Tests (DATA): endpoints stay pinned, determinism, parallel wires converge in the middle, perpendicular wires stay unbundled, and the occlusion metric (occupancy, grid-cell ink coverage) drops >20% vs straight edges on a bipartite hairball — the de-hairballing proven as DATA.

Roadmap.

3. Topological semantic zoom — LANDED (level-1) (src/community.rs)

Approach. Louvain modularity local-moving detects communities; meta_graph collapses each community into a meta-node (centroid + member count) and aggregates crossing edges. fracture_t(zoom, …, ease) maps zoom to a fracture parameter t∈[0,1] through an injected easing curve (the same dependency-injection seam helix uses); fractured_positions lerps members from the meta-centroid (collapsed, t=0) to their real positions (open, t=1) — the meta-node blooms apart instead of popping. visible_count is the LOD: meta-count when out, node-count when in.

Tests (DATA): two-cluster detection with Q>0.3, determinism, meta-node count < node count at low zoom, fracture eases collapsed→open monotonically, fractured positions lerp as DATA.

Roadmap.

4. Mental-map stability (helix) — LANDED (facett-helix/src/stability.rs)

Approach. Dynamic-graph layout stability via anchor constraints. Per node per timestep we minimise ‖pₜ−rawₜ‖² + λ‖pₜ−pₜ₋₁‖²; the closed-form minimiser is the one-line anchor pₜ = (rawₜ + λ·pₜ₋₁)/(1+λ), so per-step travel is bounded by ‖rawₜ−pₜ₋₁‖/(1+λ) — what moves is what changed, preserving the user's spatial memory instead of teleporting. The angular coordinate eases along the shortest arc (wrap-aware). The time axis maps to helix depth: each timestep is a cross-section stacked along the axis, and a node's anchored positions across the steps are the control points of a rubberband spline (trajectory_world → catmull_rom_chain) — the user flies through structural history and sees how a node migrated across system boundaries over commits/runs.

Tests (DATA): λ=0 reproduces the from-scratch baseline; anchored per-step travel is bounded by Δ/(1+λ) and >2× below the from-scratch teleport; an unchanged node stays exactly put; the trajectory advances monotonically through the time-depth; determinism.

Roadmap.


Build / test notes