Organic Modularity · Note IV

A field guide to boundary-crossers

A boundary-crosser is a node in a dependency graphIn our case, a representation of dependencies in a software system. Nodes stand for a program's parts — modules, classes, functions. A directed edge A → B means A refers to B. Clusters are sets of densely-connected nodes, and an edge crosses a boundary when it connects a node inside a cluster to a node outside it. whose edges cross the boundary of its own cluster. Sometimes those are accidents and tangle the code; and sometimes they're intentional, and structurally necessary. But every partition-based coupling metric confuses the two. This note names three species of legitimate crossers, provides descriptive characteristics and metrics for all three — plus the actions that produce them, and the unintentional impostors that mimic them. We validate all against small, runnable Python programs.

01 — The unfinished business

The patch that led the way

Every coupling metric in the partition familyMetrics computed on a partition: a division in which every node belongs to exactly one cluster, with no overlaps. The family includes CK's coupling suite, Newman modularity, and our own v2 pipeline — anything that begins by drawing hard, disjoint boundaries. — from Chidamber & Kemerer through Newman modularity to our own v2 pipeline — treats a cluster boundary as a wall, and counts every edge that crosses it as a problem.

But a node whose edges cross its cluster's boundary is not always evidence of tangle. A coordinator that wires four workers together will always have more cross-boundary edges than those workers. A metric that flags it as disorder isn't being strict; it's simply judging the situation incorrectly.

Our v2 metrics handled one such case with a patch: the CCR orchestrator exclusionOur v2 rule: detect the one cluster whose job is integration (highest cross-boundary edge volume, out-ratio ≥ 0.60, a clear lead over the runner-up) and exclude it from the worker CCR average, so the wiring layer doesn't poison the score of the modules it wires.. Detect the one integration class, drop it from the worker average, move on. It worked — on the 100-program benchmark it fires on 42 of 47 decomposed programs and on none of the unconstrained ones. But it always had the smell of a special case: a hand-tuned exception, carved out of a metric that was otherwise treating every crossing as a sin.

Note III raised the suspicion that the patch was a shadow of something general — that Alexander's semi-latticeAlexander's name for a structure whose clusters may overlap without nesting — as opposed to a tree, where any two clusters either nest or are disjoint. The subject of Note III., measured as overlapping community membership, might subsume the orchestrator rule. We tested that suspicion on our own artifacts. It failed, and the failure was more instructive than the hypothesis.[1]

What the measurement said

A well-decomposed orchestrator is not an overlap node. It is a star center — a hub whose neighbours connect to it but not to each other — and a star has no overlap structure at all. The orchestrator exclusion is not a special case of the overlap criterion. Both are members of a family of legitimate boundary-crossers, and the family has (at least) three species, told apart by two independent axes.

This note is the field guide to that family: the field identifiers for each species, live measurements of each on small runnable programs, the programming movements that produce them by different means, the unintentional impostor that mimics all of them, and a census across the published 100-program benchmark showing that the species are not decorative — they are what decomposition produces.

02 — The two axes

Direction, and embedding

Call a node a boundary-crosser when its edges cross the boundary of its cluster — when it is connected to nodes in clusters other than its own. Every legitimate boundary-crosser answers two independent questions about how it participates in more than one region of the graph.

Direction — does dependency flow out of the node, in to it, or both? Measured by the out-ratioout_ratio(v) = out-degree / (in-degree + out-degree) on the directed dependency graph. 1.0 = pure coordinator (only calls out); 0.0 = pure kernel (only gets called); 0.5 = balanced., a single number on the directed graph.

Embedding — is the node the center of a starA hub whose neighbours are mutually independent — they connect to the hub but not to each other. A star has zero triangles, which means link clustering has nothing to grip., or is it woven into several dense regions at once? Measured by m(v)The number of link communities (Ahn, Bagrow & Lehmann 2010) incident on node v. Link clustering groups edges, so one node can sit in several edge-communities at once — m(v) > 1 is measured overlap., the node's community-membership count under overlapping community detection, together with its triangle participationHow many triangles (3-cycles) the node sits in. Zero triangles = its neighbours don't know each other = star embedding. Many triangles = it lives inside dense, mutually-connected regions..

Two axes, three occupied cells:

ORCHESTRATOR

Out-directed · star center

High out-degreeout-degree = the number of edges leaving a node; in-degree = the number arriving. On a dependency graph: how many parts this node uses, and how many parts use it., out-ratio ≥ 0.60, zero triangle participation — the nodes it coordinates (its workers) are mutually independent, which is exactly what makes it a good orchestrator. Low m(v), by construction: a star has no overlap for link clustering to find.

SHARED KERNEL

In-directed · star center

The mirror image: high in-degree, out-ratio ≤ 0.40, zero triangles. Everything refers back to it; it refers to nothing. Its strength is not activity but being depended upon.

BROKER

Bidirectional · multiply-embedded

The one true overlap node: m(v) > 1 under link clustering. It is woven into several dense regions at once — its edges belong to different edge-communities, and it is the shared member.

Try the classifier. It is the exact rule set we run in code (§10), including the guard the measurements forced on us — a high out-ratio node woven into triangles is not an orchestrator, just a busy resident of a dense region:

Fig. 1 — The species classifier, live
verdict
Orchestrator
The embedding axis dominates. If m(v) > 1 the node is a broker no matter which way its edges point — being woven into two regions outranks the direction of flow. Only on a star (zero triangles) does direction split the species.
03 — The species zoo

Descriptive characteristics, in motion

Watch the dependency flow. The three species are easiest to tell apart by where the particles go.

Fig. 2 — Three species, three flows
Orchestrator — flow out
Shared kernel — flow in
Broker — woven through
Left: the orchestrator's dependencies flow outward to workers that never talk to each other. Middle: the kernel receives; its callers are mutually independent. Right: the broker sits where two dense regions overlap — the lime node belongs to both translucent fields at once, and flow moves through it in both directions.
orchestrator shared kernel broker / overlap worker

Alexander's names fit these shapes with almost no forcing, and we will come back to that in §11 — the broker is his Deep Interlock and Ambiguity, the kernel his Void, the orchestrator his field of centers, with one honest caveat about hollow hubs. But the field guide comes first: each species, on a real program, with the instruments running.

04 — Plates I–III

The species, measured

Each plate below is a small runnable Python program, designed to exhibit one species cleanly, then parsed and measured by the same pipeline we run on the benchmark. The numbers shown are the pipeline's actual output, not illustrations.

Plate I — the orchestrator, ReportRunner

class ReportRunner:
    """The star center: coordinates all four workers; none call back."""
    def __init__(self):
        self.loader   = Loader()
        self.cleaner  = Cleaner()
        self.analyzer = Analyzer()
        self.renderer = Renderer()

    def run(self, path):
        rows   = self.loader.load(path)
        rows   = self.cleaner.clean(rows)
        totals = self.analyzer.totals_by_region(rows)
        return self.renderer.render(totals)
Fig. 3 — Plate I · class-level graph, measured
out_ratio
1.00
triangles
0
m(v)
1
link comms
1
partition D
0.000
species
orchestrator
The negative result, visible. Link clustering collapses the whole star into one community — partition densityD, the quality function of link clustering (Ahn et al.): how densely each edge-community is connected internally, averaged over communities. The algorithm cuts where D peaks; D ≈ 0 means no edge-community structure worth the name. 0.0, every node at m(v)=1. A star has no edge-similarity structure to grip: the orchestrator's neighbours don't share neighbourhoods, which is precisely why it shows no overlap. Overlap machinery cannot see this species. Direction can: out_ratio 1.00.

Plate II — the shared kernel, Money

class Money:
    """The kernel: high in-degree, zero out-degree."""
    def __init__(self, cents): self.cents = int(cents)
    def plus(self, other):  return Money(self.cents + other.cents)
    def times(self, factor): return Money(round(self.cents * factor))

# Pricing, TaxCalculator and ReceiptPrinter each construct Money.
# None of them reference each other. Money references nothing.
Fig. 4 — Plate II · class-level graph, measured
out_ratio
0.00
in-degree
3
triangles
0
m(v)
1
partition D
0.000
species
shared-kernel
The same star, mirrored. Identical embedding to Plate I — one community, zero overlap, zero triangles — but the flow runs the other way: out_ratio 0.00. The direction axis is the only thing separating these two species, and it separates them perfectly. A kernel's strength is being depended upon.

Plate III — the broker, SyncBridge

class SyncBridge:
    """The broker: belongs to the local world AND the remote world."""
    def __init__(self):
        self.store = LocalStore()          # local cluster (a triangle)
        self.index = LocalIndex(self.store.cache)
        self.api   = RemoteAPI()           # remote cluster (a triangle)
        self.queue: "RemoteQueue" = self.api.queue

    def sync(self, key, value):
        self.store.save(key, value)
        self.api.send({key: value})
Fig. 5 — Plate III · class-level graph, measured
m(SyncBridge)
2
link comms
2
triangles
4
partition D
0.667
overlap index
0.143
species
broker
Where link clustering finally grips. The two clusters are triangles, so edge-similarity is real, and the algorithm splits the ten edges into exactly two communities — the local five and the remote five. SyncBridge is the only node in both: m(v)=2, measured overlap, Alexander's interlock as a membership count. Note the guard at work: LocalStore has out_ratio 0.67 — orchestrator territory — but it sits in two triangles, so it is not a star center, and the classifier correctly leaves it a worker.
05 — The founding accident

The negative result, and what granularity does

This taxonomy was not designed. It fell out of a hypothesis failing in a useful direction.

The hypothesis, raised in Note III, was tidy: the orchestrator exclusion is a special case of the overlap criterion — run overlapping community detection and orchestrators will surface as high-membership nodes, no hand-tuned rule needed. Plate I is the refutation. On the decomposed fan-effect project from our benchmark — 12 classes, 12 edges at class level — link clustering returns partition density D = 0.018 and max m(v) = 1. Every node, including the orchestrator FanEffectSimulation, sits in exactly one community. The better the decomposition, the more star-like the orchestrator, the less overlap there is to see.

So overlap does not subsume the orchestrator rule. They catch different members of the same family — which is what makes it a family. And direction does real discriminating work where overlap is blind. On a designed two-species program (one coordinator, one shared document type, two parsers between them), the out-ratio separates the species with no ambiguity:

Fig. 6 — the direction ladder, measured
Importer1.00
CsvParser0.50
JsonParser0.50
Document0.00
out_ratio, per node. The coordinator at 1.00, the kernel at 0.00, ordinary workers in the middle at 0.50. The 0.60 / 0.40 thresholds in the classifier are conservative cuts through an empty region — on clean structure, nothing lives between the rungs.

Then granularity complicates the picture — honestly, and measurably. The same fan-effect project, parsed at method level (50 nodes, 27 edges), stops being a star: partition density rises to 0.115, eight link communities appear, and four nodes go multi-member — StimulusGenerator at m=3, FanEffectSimulation, Chunk and StatsReporter at m=2. The class-level star dissolves into method-level interlock.[2] The orchestrator that showed no overlap at one scale is a mild broker at the next scale down.

Meanwhile the unconstrained version of the same project — the tangled one — shows zero overlap at both granularities: one blob, one community, nothing to interlock because nothing was ever separated. Overlap is not noise that decomposition removes. Overlap is structure that only decomposition can create.

06 — Movements

Same species, different means

The species are structural, not stylistic. Different programming movements produce the same graph fauna by entirely different mechanisms — and one movement can hide a species from the parser altogether.

Functional composition breeds orchestrators

def build_pipeline():
    """The composition point: the only function that knows the others."""
    stages = [parse, validate, convert, summarize]
    def run(raw):
        value = raw
        for stage in stages:
            value = stage(value)
        return value
    return run

Measured at function level: build_pipeline has out_ratio 1.00, zero triangles, m(v)=1 — orchestrator, the identical signature to ReportRunner's, achieved with no objects at all. The four stages are pure and mutually ignorant; the composition point is where all the knowledge of the whole lives. Functional programming does not abolish the coordinator; it concentrates it into one honest, stateless place — which is the best version of this species. Hughes (1990) argued that composition is the modularity mechanism of FP; the graph agrees.

Aspect weaving: the kernel and the invisible kernel

A cross-cutting concern — tracing, in this exemplar — is the classic shared kernel: every domain class refers to it, it refers to nothing. But whether the parser can see that depends on the weaving mechanism, and the difference is exactly one toggle:

Fig. 7 — one concern, two weavings, measured
in(trace)
3
out_ratio(trace)
0.00
species(trace)
shared-kernel
what the AST sees
@trace on 3 methods → 3 real edges
Decorator weaving is honest to static analysis. @trace is a Name reference; the AST draws Orders → trace, Billing → trace, Shipping → trace, and the kernel manifests: in-degree 3, out_ratio 0.00, star embedding.

Flip the toggle. The config-woven version wraps the same three methods at runtime from a list of string targets — "PlainOrders.place" — and the AST edge count for trace drops from three to one (the weaver itself). The runtime dependency graph is identical; the measured graph is not. Static AOP is weave-blind: the parser sees the loom, never the cloth. This is not a flaw in the species — the kernel is still there at runtime — it is a measured limit of AST-based instrumentation, and any tool in this family must say so out loud. Kiczales et al. (1997) promised that aspects would make cross-cutting structure explicit; the decorator form keeps that promise to the parser, the config form breaks it.

07 — The look-alike

The unintentional impostor: a god object

Field guides warn about look-alikes. A god object, one that is built to do too much, has edges that cross into every cluster in sight — and match the descriptive characteristics of no species in our good boundary-crossing zoo.

class Kiosk:
    """High in-degree AND high out-degree; mutable state that every
    collaborator reaches back through."""
    def __init__(self):
        self.dirty = True              # shared mutable state
        self.log = Log(self)            # Kiosk → Log,  Log → Kiosk
        self.db  = Db(self, self.log)   # Kiosk → Db,   Db → Kiosk …
        self.net = Net(self, self.db, self.log)
        self.ui  = Ui(self, self.net, self.log)
Fig. 8 — the god object, measured
in / out (Kiosk)
4 / 4
out_ratio
0.50
triangles(Kiosk)
5
Q
0.000
species
— none —
flag
⚑ bidirectional hub
Every rule refuses it. Not a broker: m(v)=1 — the graph is so uniformly dense that link clustering finds one community, not several to straddle. Not an orchestrator and not a kernel: out_ratio 0.50 sits dead in the excluded middle, and five triangles of participation fail the star-embedding guard twice over. What fires instead are the instruments: modularity QQ (Newman–Girvan): the fraction of edges falling inside clusters, minus the fraction expected if edges were placed at random. Q > 0.3 marks real community structure; Q ≈ 0 marks none. Computed with the Louvain algorithm; thresholds in §10. = 0.000 — Alexander's fully-coupled Case 2, no community structure at all — and the §4.4 bidirectional-hub flagFrom the paper: a node in the top of both the in-degree and out-degree distributions. Dangerous because change propagates through it in both directions — and doubly so when it carries shared mutable state, which is the exact mechanism Alexander's model identifies as the source of intractability., which Kiosk trips uniquely.

This is the deepest point in the guide, so it deserves plain words: the species names describe structure, not virtue. The classifier does not bless a node by calling it an orchestrator, and it does not condemn the god object by name-calling — it simply finds that the god object has no legitimate structural niche. Its signature — bidirectional flow, dense embedding without multiple memberships, balanced ratio, shared mutable state — is the signature of a node that disturbs settled subsystems from the inside, the precise mechanism that makes adaptation exponential in Note I.

The wild confirms the designed exemplar. In the unconstrained half of the benchmark, wa07_api_client.py grows a function called _call that is the top of both degree distributions at once — a bidirectional hub in its natural habitat. Its decomposed twin has no such node; the flow has been straightened into an orchestrator and a set of kernels.

08 — The census

Decomposition creates the species

If the three species are real, they should be produced by decomposition and absent from tangle. We ran the classifier across the full published benchmark: fifty specifications, each implemented unconstrained (L0) and decomposition-first (L2), method-level graphs, identical pipeline.[3]

Fig. 9 — species census, 50 specs × 2 conditions
unconstrained (L0)decomposed (L2)
files w/ orchestrator 18 / 50 44 / 47
files w/ shared kernel 10 / 50 47 / 47
files w/ broker 2 / 50 16 / 47
mean overlap index 0.004 0.044
v2 orchestrator rule fires 0 / 50 42 / 47
The species are what decomposition looks like from inside the graph. Every decomposed program grows at least one shared kernel; nearly every one grows an orchestrator; a third grow genuine brokers with measured overlap (up to 0.316 in cl09_task_runner). The unconstrained programs grow almost none of this — two files with any overlap, one with any triangle structure. And the old hand-tuned v2 rule agrees with the new species classifier: of the 42 decomposed programs where the cluster-level orchestrator rule fires, the node-level classifier finds an orchestrator inside that same cluster in 40.

Two readings of that last row. First, the v2 patch was right — it was measuring a real species with a cheap instrument, which is why it never misfired on tangled code. Second, the patch is now redundant — the family classifier catches the orchestrator and the two species the patch could never see, from first principles, with no magic 2×/+4 lead thresholds.

The wild specimens are worth a naturalist's note. The brokers that appear in decomposed code are recognizably Alexander's drugstore-at-the-traffic-light: su01_logger's handlers belong at once to the logging core and to their output subsystems; wa06_validator's ErrorCollector is shared tissue between validation passes (overlap 0.312, with real triangles). Nothing in the prompt asked for brokers. They grew where two well-formed regions genuinely needed a shared member — which is the semi-lattice thesis of Note III, observed in generated code.

09 — The species under change

Incremental deltas: the zoo, sanity-checked

Modern AI code evaluation is incremental: a change is accepted when its unit tests pass. Adding an edge to a dependency graph is behaviour-preserving — every change below clears that bar — so the question is whether the instruments register anything at all at this granularity.[4]

The protocol: take the 47 decomposed benchmark programs and apply to each a stream of thirty realistic, test-passing changes — bug fixes, performance work, dependency updates that break a contract, new features — in two paired arms with identical intents. The hygienic arm does the work with awareness of the species: its crossing edges land on shared kernels or on new adapter nodes at the boundary, and its features attach inside one cluster. The sloppy arm does the same work by convenience: patches reach wherever needed, performance shortcuts skip layers, and a kernel whose contract broke adapts by reaching outward. Every instrument is then read against the structure detected before the stream began.

Fig. 10 — median Q under thirty test-passing changes, measured
Q = 0.15 alert 0.0 0.4 PR 1 10 20 30 hygienic 0.413 sloppy 0.041
The compounding curve, and its counterfactual. Same programs, same change intents, same random stream — the only difference is where the crossing edges land. The sloppy arm's median Q decays 0.278 → 0.041, crossing the alert at the ninth change; the hygienic arm rises to 0.413 and never alerts, separating in 47 of 47 programs (paired t = 7.0 from the first change).

Three lessons, each measured. First, deltas are only meaningful against a pinned reference. Re-running community detection after each change inverts the signal — it answers "how modular is the best reading of the new graph," not "did this change respect the structure we had." Pinned to the pre-change clustering, the gradient comes out right: a single edge added inside a community moves Q by noise around zero; a single lateral crossing trends negative; and a single kernel-poke — a settled kernel acquiring an outward crossing edge, the exact disturbance of Note I's model — is sign-negative in 99% of trials and flips the kernel's species classification at the touched node in 94%. The classifier turns a delta into a reviewable sentence: this change demotes this kernel.

Second, the instruments divide the labour. Worker CCR is the leading indicator — the sloppy arm crosses its 0.6 alert at the second change. Q is the confirmatory one — slower but statistically strongest. And raw BVC fails as a gate: it false-alarms on the hygienic arm's legitimate kernel traffic at the very moment it catches the sloppy arm. It becomes clean only as species-aware BVC, which forgives a crossing edge that lands on a kernel or routes through an adapter: the hygienic arm then holds at 0.000 for all thirty changes while the sloppy arm still alerts at the second. This is the sharpest result of the sanity check — the quantitative metric is unusable without the qualitative zoo.

Third, the overlap index is a shape, not a gate. At the first change the hygienic arm shows more overlap than the sloppy one (paired t = +4.7): healthy work creates modest, legitimate interlock. By the thirtieth the relationship has inverted — sloppy overlap balloons to 0.73 against hygienic 0.44, higher in 45 of 47 programs — because once crossing edges are pervasive, every node sits in several edge-communities, and overlap stops meaning interlock and starts meaning boundaries dissolving. Overlap is ∩-shaped in health: near zero is a tree or an undifferentiated blob; moderate is a living semi-lattice; runaway is mud. A city is not a tree — and it is not a soup.

10 — The instrument panel

The classifier, exactly as it runs

The whole field guide compresses into one function plus one flag. This is the code, verbatim from the pipeline that produced every number above.

def classify(m_v, ratio, tri_v, in_d, out_d):
    """Species classifier. The two axes are BOTH required.
    Star species additionally require star embedding: zero triangle
    participation. A node woven into triangles with a high out-ratio
    is not an orchestrator — just a busy resident of a dense region."""
    if ratio is None:                                  # isolated node
        return "worker"
    if m_v > 1:                                       # embedding axis first
        return "broker"
    if tri_v == 0 and out_d >= 2 and ratio >= 0.60:  # star + out-flow
        return "orchestrator"
    if tri_v == 0 and in_d >= 2 and ratio <= 0.40:   # star + in-flow
        return "shared-kernel"
    return "worker"
instrumentreadsthreshold / rulecatches
out_ratio(v)direction of flow on the directed graph≥ 0.60 out · ≤ 0.40 inorchestrator vs. kernel, on stars
m(v)link-community memberships (Ahn et al.)> 1the broker — measured overlap
triangles(v)embedding: star vs. woven= 0 required for star speciesthe guard — busy residents ≠ hubs
overlap indexfraction of nodes with m(v) > 1granularity-sensitivehow semi-lattice the whole system is
Qpartition modularity (LouvainA fast greedy algorithm (Blondel et al. 2008) that searches for the partition maximising Q. Non-deterministic between runs — pin the seed, or pin the partition itself when computing deltas (§09).)< 0.15 alertCase-2 tangle — no structure at all
bidir-hub flagtop of both degree distributionsin & out maxima, > 1the god object — the look-alike
The granularity caveat, as a rule of use

Link-community measures need triangle density to grip. On sparse class-level star graphs, m(v) collapses to 1 and only the direction axis is informative — that is honest (a star truly has no overlap), not broken. Compute the overlap instruments at method-level granularity or on genuinely dense graphs; read m(v) > 1 as a strong broker signature when the node also participates in triangles, and as a weak junction signature when it does not.

And one rule from the incremental experiments of §09: compute every delta against a pinned reference — the structure detected before the change — never by re-running detection afterwards, which answers a different question.

What the panel replaces: one hand-tuned exception (detect-and-exclude the orchestrator) becomes a principled statement — nodes with a legitimate structural niche have their cross-boundary edges scored as structure, not violation — plus an enumeration of the niches, each independently measurable, each observed both in designed exemplars and in the wild.

11 — Where this goes

Three notes of a melody

The reason this family felt familiar is that we had walked into Alexander's mature subject from the graph side.

His later theory is built on centers — regions that draw their strength from the centers around them — and the family's two axes are his two relational questions. The embedding axis is his distinction between a center that anchors a field and one that interlocks fields; the direction axis, between a center that organizes its neighbours and one that is depended upon by them. The broker is his Deep Interlock and Ambiguity, almost definitionally — interlock is overlap, stated once in prose and once in membership counts. The kernel is his Void and his Not-Separateness: the still core everything refers back to, the node least separable from the rest. The orchestrator is his field of centers, with the caveat he might insist upon: a hub whose workers are hollow is a controller, not a living center, and that difference — workers with real internal cohesion versus workers that exist only to be called — is measurable, and our CCR already gestures at it.

Discipline requires the other half of the sentence: this correspondence covers four of his fifteen properties — the relational ones — and says nothing about the other eleven, which concern a center's internal life or continuous geometry. And his centers are recursive — made of smaller centers, strengthened by them — where our species are, so far, computed flat, at one granularity. §05 showed the flat picture is already granularity-sensitive: the class-level star dissolves into method-level interlock. The genuinely Alexandrian version is the recursion — species at every level, with the strength of a center at one level a function of the strengths of the centers composing it. That fixed-point — a center is strong to the degree that strong centers support it — is the eigenvector centrality question, and part of our current research, not this note.

A field guide helps to build a descriptive theory. Alexander's theory of centers is an explanatory theory. — where Note V begins
[1]The test that failed: run link clustering (Ahn, Bagrow & Lehmann 2010) on our benchmark orchestrators and look for high membership counts. Result, reproduced in §04–05: on class-level graphs the orchestrators sit at m(v) = 1 with partition density ≈ 0 — no overlap at all, because a well-decomposed star has no edge-similarity structure. The hypothesis was refuted on our own artifacts before a word of this note was written, which is the order these things should happen in. ↩
[2]Measured on the decomposed fan-effect simulation from the benchmark. Class level: 12 nodes, 12 edges, 0 triangles, D = 0.018, max m(v) = 1. Method level: 50 nodes, 27 edges, D = 0.115, overlap index 0.080, with StimulusGenerator at m = 3 and FanEffectSimulation, Chunk, StatsReporter at m = 2. The unconstrained twin: zero overlap at both levels. All numbers re-measured for this note with the v3 engine; they match the working-notes values to the third decimal. ↩
[3]47 of the 50 decomposed files parse; three (dp09, wa08, wa10) contain unterminated string literals — generation truncation artifacts — and are excluded from both the published benchmark's usable rows and this census. Species totals at node level, decomposed condition: 99 orchestrators, 221 shared kernels, 45 brokers across 1,022 nodes; the per-file counts shown are the conservative reading (class nodes and their __init__ methods can both classify, so "files containing ≥ 1" avoids double counting). ↩
[4]Per-change numbers: 423 matched single-edge trials (141 per change type). Streams: 47 programs × 30 changes × 2 arms; change mix 40% bug fix, 20% performance, 15% contract-breaking dependency update, 25% feature; both arms consume the same random intent stream; Q pinned to the Louvain partition (seed 42) of the pre-stream graph; worker CCR alert at 0.6, BVC alert at 0.05, all against the same pinned reference. Scripts ship in the note's companion package. ↩

References & notes

  1. C. Alexander, The Nature of Order, Books 1–4. Center for Environmental Structure, 2002–2004. Centers, the fifteen properties, and the field of centers.
  2. C. Alexander, “A City Is Not a Tree,” Architectural Forum, vol. 122, 1965. The tree / semi-lattice distinction — Note III's subject and this note's foundation.
  3. C. Alexander, Notes on the Synthesis of Form. Harvard Univ. Press, 1964. The equilibration-time argument of Note I.
  4. G. Bryant & G. Williams, “The Necessity of Organic Modularity, and Metrics for Eliminating Compound Overcoupling in Generative Code,” 2025. https://zenodo.org/records/21015575 — the paper this series extends; §4.4 defines the bidirectional-hub metric used in §07.
  5. Bryant & Williams, v2 metrics benchmark: 50 specifications × (unconstrained, decomposed-first), 100 Python programs, with per-spec Q, CCR, BVC and orchestrator detection. The corpus of §08.
  6. Y.-Y. Ahn, J. P. Bagrow & S. Lehmann, “Link communities reveal multiscale complexity in networks,” Nature, vol. 466, pp. 761–764, 2010. The overlap machinery: m(v) and partition density.
  7. V. D. Blondel, J.-L. Guillaume, R. Lambiotte & E. Lefebvre, “Fast unfolding of communities in large networks,” J. Stat. Mech., P10008, 2008. Louvain, used for Q.
  8. M. E. J. Newman & M. Girvan, “Finding and evaluating community structure in networks,” Phys. Rev. E, vol. 69, 026113, 2004. Modularity Q.
  9. S. R. Chidamber & C. F. Kemerer, “A Metrics Suite for Object Oriented Design,” IEEE Trans. Software Eng., vol. 20, no. 6, 1994. The partition-family ancestor; its own data flagged mediator classes as “high coupling.”
  10. E. Gamma, R. Helm, R. Johnson & J. Vlissides, Design Patterns. Addison-Wesley, 1994. Mediator and Facade — the orchestrator's pattern-language cousins; value objects, the kernel's.
  11. G. Kiczales et al., “Aspect-Oriented Programming,” Proc. ECOOP, 1997. Cross-cutting concerns; the weave-blindness of §06 is the static-analysis shadow of their central idea.
  12. J. Hughes, “Why Functional Programming Matters,” The Computer Journal, vol. 32, no. 2, 1989. Composition as FP's modularity mechanism — the composition-point orchestrator of §06.
  13. A. J. Riel, Object-Oriented Design Heuristics. Addison-Wesley, 1996. The god class, named; our §07 gives it a measured signature.
  14. B. Foote & J. Yoder, “Big Ball of Mud,” Proc. PLoP, 1997. The unconstrained condition's natural endpoint, described before LLMs could generate it at scale.