ek9_query_module_coupling
Answers first: status, programState, edgeCount, then edges[] {from, to, types, weight, shape, sites, inCycle, proposals} ranked worst-first, audit (adHocCoupling, overDeclaredReferences candidates) and summary.
When to use it
'Which types leak across which module boundaries, and how heavily' is one call with no arguments - every cross-module edge ranked worst-first, with sites.
When not to use it
- the per-module enforced coupling number and band, the E11016 gate (use
ek9_query_module_landscape; this is the edge breakdown behind it) - confirming a declared 'references' entry is truly removable (use
ek9_organize_references, a scratch compile; overDeclaredReferences here surfaces candidates only) - per-construct coupling with the 0.5-per-'by'-delegation discount, E11015 (use
ek9_query_construct; module edges are whole-number binary dependencies)
Details
Read from RESOLVED symbol type-references (super/traits/field/param/return → edges by FQN); generics are unwrapped so List of Order couples to Order, not to org.ek9.lang. Each edge carries {from, to, types[], weight, declared, adHocFqn, shape{concentration, nearMutualityRatio, targetAbstractness}, sites[{file,line}], inCycle, proposals[]}; weight is a signature-reference count, and proposals (extract-kernel / narrow-with-trait / clarify-ownership) are advisory — pair with ek9_git_log co-change evidence before acting. audit.adHocCoupling (inline-FQN coupling with no 'references' entry) is signature-derived and safe; audit.overDeclaredReferences is candidates-only, since a body-local variable-declaration type escapes even its body-aware used-set.
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
direction | string: both | outgoing | incoming | With moduleFilter: 'outgoing' = edges out of those modules, 'incoming' = edges into them, 'both' (default) = either side. | |
minWeight | integer | Only edges with at least this weight (signature reference count). Default 1. | |
moduleFilter | array of string | Restrict to these modules - exact names; an entry ending in '*' is a prefix ('com.acme.*'). A single string is accepted. Omit for workspace-wide. | |
targetAbstractness | string: value | abstraction | concrete | Only edges reaching this genus class (concrete = heaviest coupling risk). |
It also takes the arguments every tool takes.
Recorded calls
Real calls, recorded against small projects and checked on every build - a changed answer fails it.
Coupling shape
Request
{ }
Response
{
"audit" : {
"adHocCoupling" : [ ],
"overDeclaredReferences" : {
"basis" : "signature ∪ injections ∪ callGraph",
"candidates" : [ ],
"note" : "candidates only — a body-only local-variable type declaration can still use a reference the call graph does not show; verify with ek9_organize_references (scratch compile) before removing"
}
},
"edgeCount" : 2,
"edges" : [ {
"adHocFqn" : false,
"declared" : true,
"from" : "sample.arch.orders",
"inCycle" : false,
"proposals" : [ ],
"shape" : {
"concentration" : 2,
"nearMutualityRatio" : 0.0,
"targetAbstractness" : "value"
},
"sites" : [ {
"file" : "orders.ek9",
"line" : 10
...
Cut short here: 33 more lines. The whole recorded call.