At commit a76adc3, ruvnet/RuView contains 13,799 analyzed functions, 779 of which land in the critical band. The top of that list is dominated by a single file: v2/crates/wifi-densepose-sensing-server/src/main.rs, whose two functions — udp_receiver_task (CC 88, activity-weighted risk 18.98) and main (CC 96, activity-weighted risk 18.92) — were both modified within the last 24 hours and sit in the fire quadrant, meaning they are structurally complex and actively changing right now. I would start there, not because the code is poorly written, but because extreme branching combined with continuous commit activity is where live regressions are most likely to emerge.
The table below ranks functions by activity-weighted risk — a score that multiplies structural complexity by recent commit frequency. A function that is both hard to understand (high cyclomatic complexity) and actively changing is a higher priority than one that is complex but untouched. CC = cyclomatic complexity (independent execution paths); ND = max nesting depth; FO = fan-out (distinct callees).
Top 5 Hotspots
| Function | File | Risk | CC | ND | FO |
|---|---|---|---|---|---|
udp_receiver_task | v2/crates/wifi-densepose-sensing-server/src/main.rs | 19.0 | 88 | 6 | 58 |
main | v2/crates/wifi-densepose-sensing-server/src/main.rs | 18.9 | 96 | 5 | 84 |
main | scripts/train-wiflow.js | 18.8 | 53 | 6 | 69 |
main | scripts/train-camera-free.js | 18.4 | 93 | 6 | 109 |
GaussianSplatWebViewWeb | ui/mobile/src/screens/LiveScreen/GaussianSplatWebView.web.tsx | 18.0 | 17 | 7 | 109 |
Large Repo Analysis
RuView is a large repository. To stay within memory constraints, this analysis used hybrid touch mode: structural complexity — CC, ND, FO — is measured precisely for every function. Git activity is tracked at the function level (via git log -L) only for files with 5 or more commits in the last 30 days; other files use a file-level approximation. Rankings therefore surface functions that are both structurally complex and in the most actively-changing parts of the codebase. Dormant code with high structural complexity will rank lower than it would under a full per-function analysis — to surface it, run hotspots analyze . --per-function-touches on a machine with sufficient memory.
13,799 functions analyzed
One detail from the quadrant breakdown stands out immediately: there are zero debt-quadrant functions in this repository. Every high-complexity function is also seeing active commits, so the structural risk here is not dormant — it is being exercised continuously, which is exactly the condition where refactoring has the highest near-term payoff.
High cyclomatic complexity — many independent execution paths, each a potential bug surface and required test case.Deeply Nested×5Deeply Nested
Control structures nested 4+ levels deep, making it hard to reason about the full execution state at inner branches.Exit Heavy×5Exit Heavy
Multiple return or throw paths dispersed through the body — each exit needs separate test coverage.God Function×5God Function
Calls an unusually large number of distinct functions (high fan-out), making it the structural centre of gravity for a subsystem.Long Function×5Long Function
Function body is too long to review in a single pass; likely contains multiple distinct responsibilities.Hub Function×1Hub Function
Many other functions call this one — a change here ripples widely through callers.
Every function in the top five carries all five of the most severe antipattern flags: complex branching, deep nesting, multiple exit paths, god-function coupling, and excessive length. That sweep is not coincidental — it reflects a design pattern where large, multi-responsibility async functions absorb new hardware protocol support directly rather than delegating to purpose-built handlers.
udp_receiver_task — main.rs
A cyclomatic complexity of 88 means there are 88 independent execution paths through this function — each a potential bug surface and, in principle, a required test case. The fifth-ranked function on this list has CC 17. That 71-point gap is not a matter of degree; it represents a qualitatively different kind of function that needs different treatment.
From the source excerpt, udp_receiver_task is an async loop that binds a UDP socket and dispatches incoming datagrams across at least four hardware protocols: ESP32, MediaTek CSI, Qualcomm CSI, and RTL8720F radar frames, plus a vendor RF event path. Each protocol adds its own match arms, guard clauses, error branches, and shared-state write paths — all inside a single loop body. The nesting depth of 6 reflects the layered match-inside-if-inside-loop structure visible in the excerpt, and the fan-out of 58 means changes here can ripple into 58 distinct callees.
External signals show a bug-fix fraction of 0.29 across 7 total commits, with 2 authors active in the last 90 days — no bug-linked commits or reverts, which is worth noting, but the fraction of commits classified as fixes is meaningful context. This function was touched 6 times in the last 30 days and was last modified 1 day ago. That is a live regression risk.
The allowlist admission path (ADR-296), the four protocol dispatch branches, the shared-state write under an async write lock, and the JSON broadcast all belong in separate, independently testable units. I would start the refactoring by extracting a dispatch_frame function that accepts a raw &[u8] slice and returns a typed ParsedFrame enum — one variant per protocol. That extraction alone eliminates the deeply nested match chains from the hot loop and brings each protocol’s parsing path into testable isolation.
main — main.rs (sensing server)
The main function in the same file has a higher cyclomatic complexity than udp_receiver_task — 96 versus 88 — but scores fractionally lower on activity-weighted risk because it was touched 5 times in 30 days rather than 6. Both scores are effectively tied at the top of the repository’s risk profile.
The source excerpt shows this function serving as the application’s entire initialization and branching hub: CLI argument parsing, a benchmark-mode early exit, a model-conversion early exit, an RVF export mode with a conditional placeholder warning (referencing issue #894 explicitly in comments), and then telemetry setup, training pipelines, and the server itself. The fan-out of 84 is the highest of any function in the top five — nearly every subsystem in the codebase is reachable from here in a single call step.
The exit-heavy pattern is highly visible: the excerpt alone shows three return or process::exit paths before the function reaches its primary runtime path. Each early exit is a branch that diverges from the main initialization sequence and requires its own test fixture to cover. With 96 independent paths and 84 callees, any modification to main carries a broad blast radius.
The same external signals apply (same file as udp_receiver_task): bug-fix fraction of 0.29, 2 active authors. The concrete fix is to introduce a run_subcommand dispatcher that handles the benchmark, convert-model, and export-rvf modes as separate async functions, reducing main to argument parsing plus a single dispatch call. That alone would cut the cyclomatic complexity materially and make each mode independently testable.
main — train-wiflow.js
This is a Node.js training pipeline script — the name makes its role clear: orchestrate a multi-step CSI data training run for the WiFlow pose estimation model. The source excerpt shows it structured as a sequential 7-step pipeline (loading CSI data, extracting amplitude windows, and so on) with all steps inlined into a single async function body. With CC 53 and ND 6, the branching complexity comes from per-file loading loops, subcarrier count validation, resampling conditionals, and multiple process.exit calls guarding against bad data states.
The fan-out of 69 reflects how many utility functions this orchestrator calls directly — resolveGlob, loadCsiData, parseIqHex, extractAmplitude, and more, all invoked from the same flat function scope. This is the god-function pattern at the script level: the function knows how to do everything rather than delegating to a pipeline abstraction.
The file has only 1 commit in its history and 1 author in the last 90 days, with no bug-linked commits or reverts, and was last changed 20 days ago. Even so, CC 53 and the exit-heavy pattern mean the next developer who needs to add a training step or change the resampling logic will be reasoning about control flow across 53 paths. I would extract each numbered pipeline step into its own named async function and have main call them in sequence — a pattern that makes the pipeline stages independently testable and reduces the orchestrator to a coordinator of single-responsibility calls.
main — train-camera-free.js
The main function in train-camera-free.js is the most broadly coupled function in the top five, with a fan-out of 109 — meaning it directly calls 109 distinct functions. Its cyclomatic complexity of 93 is the second highest on the list, behind only the sensing server’s main. The file represents a 12-step camera-free training pipeline that incorporates live UDP data collection as a fallback when the dataset is small, a Cognitum Seed client probe, data augmentation, and multi-modal timeline assembly — all within one function body.
The source excerpt makes the structure explicit: the function begins with data loading, conditionally falls back to live UDP collection (with its own try/catch and outcome branches), runs augmentation, then probes the Seed endpoint with further conditional paths depending on reachability. Each of the 12 steps adds branching. The ND 6 nesting comes from the layered conditionals around the live collection fallback and seed availability checks sitting inside the step progression.
With only 1 commit in its history and 1 author in the last 90 days, the file has no bug-linked commits or reverts and was last changed 20 days ago. The risk is forward-looking: a CC 93 function with 109 callees is expensive to modify safely. I would apply the same extract-per-step refactoring, and specifically isolate the live UDP collection fallback (step 1b) and the Seed probe logic (step 2) into their own functions with clearly typed return values — those two paths alone account for several branches and are independently exercisable.
GaussianSplatWebViewWeb — GaussianSplatWebView.web.tsx
GaussianSplatWebViewWeb is a React component for the web target of the mobile UI — based on the name and path, it renders a Gaussian splat visualization of the live sensing data using Three.js. Its cyclomatic complexity of 17 is the lowest in the top five by a wide margin, but two other numbers keep it in the critical band: a nesting depth of 7 and a fan-out of 109.
The source excerpt confirms the fan-out figure: this component sets up a full Three.js scene inside a useEffect — renderer initialization, scene construction, camera placement, multiple light sources, shadow maps, ground geometry, a grid helper, and an instanced mesh for the signal field, all wired together with direct Three.js API calls. Each of those calls is a distinct callee contributing to the fan-out of 109. The nesting depth of 7 comes from the useEffect wrapping a try block wrapping the setup logic, with callbacks and inner functions adding further layers.
The god-function pattern here is a UI-layer variant: the component handles scene authoring, resource management (the cleanup callback disposes renderers, geometries, and materials), animation loop management, and frame data updates — all inside one component definition. There are no bug-linked commits or reverts in the file’s history, and it was last changed 20 days ago; this is a structural concern about future maintainability rather than a signal of past defects.
The actionable step is to extract the Three.js scene setup into a separate buildScene(container: HTMLDivElement): SceneHandle function that returns a typed handle, and move the cleanup logic into a matching disposeScene(handle: SceneHandle). That decomposition reduces the useEffect body to scene construction, animation loop registration, and cleanup registration — three responsibilities instead of twenty, and each independently testable.
Patterns Found
Antipatterns detected across the top functions in this snapshot:
| Pattern | Occurrences |
|---|---|
complex_branching | 5 |
deeply_nested | 5 |
exit_heavy | 5 |
god_function | 5 |
long_function | 5 |
hub_function | 1 |
These labels belong to two tiers — Tier 1 (structural): complex_branching, deeply_nested, exit_heavy, long_function, god_function. Tier 2 (relational/temporal): hub_function, cyclic_hub, middle_man, neighbor_risk, stale_complex, churn_magnet, shotgun_target, volatile_god.
See more analyses with these patterns: complex_branching, deeply_nested, exit_heavy, god_function, long_function.
Reproduce This Analysis
git clone https://github.com/ruvnet/RuView
cd RuView
git checkout a76adc3c2fdf715919ea2bec5cec3a26d36cce74
hotspots analyze . --mode snapshot --explain-patterns --force --hybrid-touches 5
To run the same analysis on your own codebase, run hotspots analyze . --mode snapshot in any local git repo — no configuration required.
I use Hotspots to highlight structural and activity risk — not “bad code.” I treat these findings as a prioritization aid, not a bug predictor. Editorial policy →