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
- 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.
- Slice 1 —
cgis suggest-packages (the analysis as a feature; low risk, new module).
- 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).
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):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 (
enginelands with its agent-facing consumers because it's shared core; the 4 leaves are sinks with no community).2. The metric (best-practice grounding)
anomaly.py): Ca/Ce, InstabilityI = Ce/(Ca+Ce), Abstractness, Distance-from-main-sequence. Apply at file scope within a package.quotient.py), one scale down.3. Product capability —
cgis suggest-packagesA 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)
query/drift/query/analysis/query/context/query/render/query/(core)5. Risks / constraints (these are load-bearing)
from cgis.query.X import …everywhere. Compatibility re-export shims would launder the import census (artificially smooth/inflate drift) — the exact anti-pattern Drift metric can be gamed by cosmetic re-exports (IMPORTS-layer laundering) #182 names. Either do an honest mechanical update of all import sites, or accept the census change consciously.cgis.queryas ONE domain. Splitting into sub-packages reshapes the domains →patterns.yamlbindings move → the restructure moves the measurement itself. A re-baseline + new domain bindings are part of the cost. (Already at the edge:cgis.querydrift sits at 0.18 today.)drift/*cluster is the most active zone (colleague's cgis_drift: report fit-quality (nearest-template residual) + domain coverage; surface 'no template fits' #177/Recursive-quotient: cross-scale motif analysis (fractality / mirror-symmetry) as an architecture signal #186/Recursive-quotient: cross-scale motif analysis (fractality / mirror-symmetry) as an architecture signal #186-tangle). A split touching those files = large merge conflict; sequence it for a quiet window or coordinate.6. Slices
cgis suggest-packagesis built first (so the split is data-driven and reproducible) or the cleanup is done by hand from the spike.cgis suggest-packages(the analysis as a feature; low risk, new module).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).