Skip to content

draft: Proposal: Modular Refactoring — Split 6 Coupling Hotspots#3

Merged
jeremiepas merged 9 commits into
mainfrom
refactor/modular-split-hotspots
Apr 22, 2026
Merged

draft: Proposal: Modular Refactoring — Split 6 Coupling Hotspots#3
jeremiepas merged 9 commits into
mainfrom
refactor/modular-split-hotspots

Conversation

@jeremiepas
Copy link
Copy Markdown
Owner

Summary

  • Graph analysis of the codebase (3,128 nodes, 5,713 edges, 0 bridge nodes) identified 6 modules with coupling 10-100x above the average degree (3.65)
  • This PR adds a refactoring proposal that splits each hotspot into focused sub-modules following clean architecture
  • Original modules preserved as re-export hubs for backward compatibility

Hotspots Identified

Module Degree Target Reduction
Infrastructure.Export.HTML 436 ~80 -82%
Domain.Types 342 ~40 -88%
Infrastructure.LSP.Client 292 ~25 -91%
UseCase.Extract 254 ~20 -80%
Domain.Graph 208 ~30 -86%

Refactoring Strategy

  • Domain.Types → 5 sub-modules (Node, Edge, Graph, Pipeline, Analysis) + re-export hub
  • Domain.Graph → 4 sub-modules (Core, Query, Analysis, Diff) + re-export hub (extending existing FGL pattern)
  • Export.HTML → Extract JS/CSS/HTML to templates + move VisNode/VisEdge to Domain.Export.Visualization
  • LSP.Client → 4 sub-modules (ServerMap, Transport, CapabilityParse, Extraction) + thin orchestrator
  • UseCase.Extract → 3 sub-modules (Haskell, Markdown, LSPOrchestrator) + composition orchestrator
  • Export couplingDomain.Export.Format type class to eliminate CommunityGraph mediator

Execution Plan

15 subtasks in 7 dependency-ordered batchesed. Each step must pass cabal build + cabal test independently.

Batch 1: Domain.Types sub-modules (parallel)
Batch 2: Import updates + test gate
Batch 3: Graph.Core, Export.Visualization, Export.Format, LSP.ServerMap+Transport (parallel)
Batch 4: Graph.Query/Analysis/Diff, Export.HTML templates, LSP.CapabilityParse+Extraction
Batch 5-6: UseCase.Extract splits
Batch 7: Final integration (ExportFormat + full test suite)

Full Proposal

See docs/proposals/modular-refactoring.md for complete details including subtask definitions, dependency graph, and exit criteria.

Test Plan

  • Proposal reviewed and approved
  • Each batch passes cabal build + cabal test before next batch
  • All re-export hubs verified (backward compatibility)
  • No IO leakage into Domain/UseCase layers
  • Graph degree reduced for all 6 hotspots

Jeremie added 5 commits April 21, 2026 00:23
…d by graph analysis

Graph analysis (3128 nodes, 5713 edges) revealed 6 modules with degree
10-100x above average (3.65). This proposal splits them into focused
sub-modules following clean architecture, with re-export hubs for
backward compatibility.

Hotspots: Export.HTML (436), Domain.Types (342), LSP.Client (292),
UseCase.Extract (254), Domain.Graph (208), Export cross-coupling.

15 subtasks organized in 7 dependency-ordered batches.
… sub-modules

Domain.Types (342 degree) → Node, Edge, Graph, Pipeline, Analysis sub-modules
+ re-export hub for backward compatibility.

Domain.Graph (208 degree) → Core, Query, Analysis, Diff sub-modules
+ re-export hub (extending existing FGL sub-module pattern).

All 75 tests pass. Build compiles with -Wall -Werror.
…se + Extraction

LSP.Client (292 degree) → 4 sub-modules:
- ServerMap: 30+ language→server command mappings + findLSPServer
- Transport: JSON-RPC messaging, connectToLSP, disconnectLSP
- CapabilityParse: server capability parsing from init responses
- Extraction: document symbols, workspace symbols, symbol→node/edge conversion

LSP.Client is now a thin re-export hub. All 75 tests pass.
UseCase.Extract (254 degree) → 3 sub-modules:
- Extract.Haskell: stub extraction, parse imports/decls, makeStubNode
- Extract.Markdown: doc extraction, headers, tags, wikilinks
- Extract remains the composition orchestrator (LSP dispatch, threading, merging)

All 75 tests pass. Build compiles with -Wall -Werror.
Triggered on v* tags. Uses same GHC/Cabal setup as CI.
After build + test pass, copies the binary and SHA256 checksum
to a GitHub Release via softprops/action-gh-release.
@jeremiepas jeremiepas force-pushed the refactor/modular-split-hotspots branch from bf8919e to a5e9b19 Compare April 21, 2026 07:11
Jeremie added 3 commits April 21, 2026 09:19
When HLS crashes mid-extraction, hPutBuf throws 'resource vanished
(Broken pipe)'. The sendLSPMessage call in extractDocumentSymbols
was not wrapped in catch, so the exception propagated up and killed
the entire LSP group extraction. Now returns [] on failure, matching
the error handling pattern of extractViaLSP and extractWorkspaceSymbols.
HLS runs cabal v2-repl to determine build flags before responding to
the initialize request. This can take 2-3 minutes on first run, often
causing the previous 60s timeout to fire.

Changes:
- defaultLSPConfig lspTimeout: 60 → 300 seconds
- extractAll/extractFromFile lspTimeout: 60 → 300 seconds
- Better timeout error message with HLS-specific tip
Two strategies to bridge the code-documentation gap:

1. Name alignment: doc nodes whose label matches a code node label
   get References edges (e.g. doc mentions 'Boond.Types' → code node)

2. Path alignment: doc file 'Foo.md' ↔ code file 'Foo.hs' sharing
   the same base name get References edges

Applied at all density levels (even Sparse) since code↔doc linking
is fundamental for knowledge graph navigation.

Fixes the issue where extracted graphs had 0 edges between code
and documentation nodes due to incompatible NodeId schemes.
@jeremiepas jeremiepas changed the title Proposal: Modular Refactoring — Split 6 Coupling Hotspots draft: Proposal: Modular Refactoring — Split 6 Coupling Hotspots Apr 21, 2026
Add IORef connection state to LSPClient with isProcessAlive check
and sendLSPMessageSafe that catches IOException (ResourceVanished)
instead of letting it crash the process. All extraction call sites
now use the safe send. disconnectLSP skips cleanup when already
disconnected.
@jeremiepas jeremiepas merged commit ccb043a into main Apr 22, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant