Skip to content

RFC: package-cohesion analysis — graph-driven sub-package suggestions (cgis suggest-packages) #242

Description

@zaebee

Status: RFC / design. Origin: src/cgis/query/ grew to 19 flat files spanning ≥4 distinct subsystems — a cohesion smell. A spike (this issue) confirms it's measurable and that the dependency graph itself proposes the fix. This RFC covers (a) the cgis self-cleanup and (b) generalizing the analysis into a product capability.

1. The spike — graph confirms the smell

Built the intra-package import graph of query/*.py (19 files, 19 edges) and ran hand-rolled greedy modularity (Clauset-Newman-Moore; cgis avoids NetworkX by design):

Modularity Q = 0.434   (> 0.3 = strong community structure)

cluster 1: audit, context_service, engine, prompt, snippet   (agent-facing navigation)
cluster 2: _scc, fingerprint, health, triads                 (graph-metric primitives)
cluster 3: drift, drift_service, ontology_init, quotient      (drift subsystem — cleanest)
cluster 4: analyzer, anomaly                                  (god-object / anomalies)
isolated : fqn, graph_json, mermaid, metrics                 (pure leaves, no intra-query imports)

The directory structure (flat) and the dependency graph (Q=0.434) diverge — that divergence IS the smell, now quantified. The algorithm suggests boundaries; it doesn't dictate them (engine lands with its agent-facing consumers because it's shared core; the 4 leaves are sinks with no community).

2. The metric (best-practice grounding)

  • Robert Martin's package cohesion principles — CCP (what changes together), CRP (what's reused together), REP. The organizing criterion; the graph is the evidence.
  • Coupling metrics cgis already computes (anomaly.py): Ca/Ce, Instability I = Ce/(Ca+Ce), Abstractness, Distance-from-main-sequence. Apply at file scope within a package.
  • Community detection (modularity Q + Louvain/CNM) on the intra-package import graph — high Q = natural split points; low Q = a genuinely cohesive unit where splitting would be arbitrary. This is the same machinery as the domain quotient (quotient.py), one scale down.

3. Product capability — cgis suggest-packages

A new analysis that, for any package: builds the intra-package import (and optionally CALLS) graph, runs community detection, reports modularity Q + the communities + the cross-community "bridge" edges (the cost of splitting), and flags packages whose directory layout diverges from their dependency communities. Reuses the quotient/census engine; surfaces via CLI + MCP like the other analyses. Turns "this feels messy" into a data-backed recommendation for any agent/architect.

4. cgis self-cleanup — proposed layout (data-informed)

sub-package files
query/drift/ drift, drift_service, fingerprint, triads, quotient, ontology_init, _scc
query/analysis/ analyzer, anomaly, health
query/context/ context_service, prompt, snippet, audit
query/render/ graph_json, mermaid, metrics
query/ (core) engine, fqn

5. Risks / constraints (these are load-bearing)

6. Slices

  1. Slice 0 (this RFC): decide go/no-go; pick whether cgis suggest-packages is built first (so the split is data-driven and reproducible) or the cleanup is done by hand from the spike.
  2. Slice 1 — cgis suggest-packages (the analysis as a feature; low risk, new module).
  3. Slice 2 — query/ restructure (honest import-site update + drift re-baseline + colleague coordination).

Refs: spike in-issue. Builds on quotient.py / _scc.py / anomaly.py. Related: #182 (re-export laundering), #117 (god-object decomposition — same cohesion family at class scope), #186 (motif/tangle work in the drift cluster).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions