paperclipai/paperclip’s highest risk is concentrated in two server-side files — server/src/services/heartbeat.ts and server/src/services/company-portability.ts — where extreme cyclomatic complexity meets active commit churn right now. The top-ranked function, executeRun, has a cyclomatic complexity of 99 and an activity-weighted risk score of 20.5, meaning it is both structurally extreme and actively changing — a live regression risk, not a backlog cleanup item. Across 9,949 total functions analyzed at commit 6a72faf, 612 fall into the critical band, and every one of the top 5 hotspots shares the same dangerous combination: god-function coupling, deep nesting, and high fan-out, all under active development.
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 |
|---|---|---|---|---|---|
executeRun | server/src/services/heartbeat.ts | 20.5 | 99 | 5 | 105 |
runDatabaseBackup | packages/db/src/backup-lib.ts | 20.1 | 45 | 7 | 54 |
companyPortabilityService | server/src/services/company-portability.ts | 19.7 | 93 | 6 | 249 |
importBundle | server/src/services/company-portability.ts | 19.6 | 101 | 6 | 79 |
heartbeatService | server/src/services/heartbeat.ts | 19.3 | 96 | 5 | 232 |
Hotspot Analysis
executeRun — server/src/services/heartbeat.ts
Based on its name and location in heartbeat.ts, executeRun likely drives the core execution loop for a heartbeat or health-check service — the kind of orchestration code that coordinates multiple downstream operations on each invocation. Its cyclomatic complexity of 99 means there are roughly 99 independent execution paths through this function, each a distinct test case and a distinct failure mode. With a fan-out of 105 and an activity-weighted risk score of 20.5, this function is both maximally coupled and actively changing right now — every commit is navigating 99 potential paths across 105 callees, making silent regressions highly likely.
Recommendation: Write characterization tests to lock down current behavior before touching anything, then apply extract-method refactoring to pull discrete responsibilities — likely individual health-check steps — into named sub-functions with their own test coverage. Target reducing CC below 20 per extracted unit.
runDatabaseBackup — packages/db/src/backup-lib.ts
Living in backup-lib.ts, runDatabaseBackup almost certainly manages the end-to-end database backup process — a workflow that by nature involves many conditional branches for error states, storage targets, and backup strategies. A max nesting depth of 7 is a strong refactoring signal on its own; combined with a cyclomatic complexity of 45 and fan-out of 54, the function is deeply nested, broadly coupled, and exit-heavy — meaning it has multiple return and early-exit paths that each require independent test coverage to verify safely. Its activity-weighted risk score of 20.1 places it among the top two hotspots in the dataset, meaning this backup-critical path is being changed more frequently than almost anything else in the top 5 right now.
Recommendation: The nesting depth of 7 is the most immediate readability problem — flatten the control flow using early-return guards and extract discrete backup phases (e.g., pre-checks, snapshot creation, verification, cleanup) into separately tested functions to reduce both ND and CC in each unit.
companyPortabilityService — server/src/services/company-portability.ts
As a service-level orchestrator in company-portability.ts, companyPortabilityService likely coordinates the full lifecycle of moving or exporting company data — a broad mandate reflected in a fan-out of 249, the highest in the dataset. A cyclomatic complexity of 93 and max nesting depth of 6 confirm that it branches extensively and deeply to handle the many conditions involved in data portability. Its activity-weighted risk score of 19.7 and actively-changing status mean this is not theoretical risk — it is being modified today, and with 249 distinct callees, even a small logic error propagates across a very wide surface.
Recommendation: Map the 249 fan-out dependencies before any refactoring to understand the blast radius, then decompose the service into focused sub-services (e.g., export, validation, import coordination) — each independently testable and with a fraction of the current fan-out.
importBundle — server/src/services/company-portability.ts
importBundle lives alongside companyPortabilityService in company-portability.ts, handling the inbound side of data portability — ingesting and processing imported company data. With a cyclomatic complexity of 101 (the highest in the top 5) and a max nesting depth of 6, it contains more independent execution paths than any other hotspot, meaning more edge cases to cover and more ways for a change to produce unexpected behavior. Its fan-out of 79 and shared location with companyPortabilityService mean changes here interact closely with the broader portability pipeline, compounding the risk of cross-function regressions.
Recommendation: Treat importBundle’s CC of 101 as the primary refactoring target. Map its input variants — different data formats, partial imports, error conditions — then extract each as a separately tested handler. Reducing the function to a top-level dispatcher with CC under 20 per branch is a realistic first milestone.
heartbeatService — server/src/services/heartbeat.ts
heartbeatService is the companion to executeRun in heartbeat.ts, likely defining the service’s configuration, scheduling, or lifecycle management. A cyclomatic complexity of 96 and fan-out of 232 — the second-highest fan-out in the top 5 — indicate a function that both branches extensively and reaches across a very wide set of callees. Max nesting depth of 5, while lower than some hotspots, still reflects multi-level conditional logic that compounds the readability burden when combined with the sheer breadth of its dependencies.
Recommendation: The fan-out of 232 is the most urgent concern — before refactoring, document which callees are genuinely required versus incidental dependencies. Then apply the same extract-method approach used for executeRun: pull discrete responsibilities into named sub-functions, targeting CC below 20 per unit.
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 |
cyclic_hub | 1 |
middle_man | 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.
Key Takeaways
executeRuninheartbeat.tshas a cyclomatic complexity of 99 and a fan-out of 105 — add characterization tests immediately, before the next commit touches it.runDatabaseBackuphas an activity-weighted risk score of 20.1 and a nesting depth of 7 — its exit-heavy branching means test coverage gaps here are the highest-probability source of undetected backup failures.companyPortabilityServicecalls 249 distinct functions; map that dependency graph before any refactoring attempt to avoid breaking changes across the portability pipeline.importBundlehas a cyclomatic complexity of 101 — the highest in the top 5 — making it the most test-coverage-intensive function to refactor safely.heartbeatServicereaches 232 distinct callees; its fan-out is the second-highest in the dataset and warrants a dependency audit before any structural changes.
Reproduce This Analysis
git clone https://github.com/paperclipai/paperclip
cd paperclip
git checkout 6a72faf83b3aeb35ee44da51898fe8cbce6f5002
hotspots analyze . --mode snapshot --explain-patterns --force
To run the same analysis on your own codebase, run hotspots analyze . --mode snapshot in any local git repo — no configuration required.
Hotspots highlights structural and activity risk — not “bad code.” Findings are a prioritization aid, not a bug predictor. Editorial policy →