Case file A7

Coupling First

Pick the architecture with the weaker coupling.

Layers, patterns, frameworks: pick any two architectures and the better one is the one where the parts can change without dragging each other along. Coupling is the metric. Everything else is proxy.

ByAdam LewisPublished3 May 2026Revised23 Oct 2026Reading12 minVersionv1.2ConfidenceHigh
§0b

Opinion

I've watched architects argue layers vs hexagonal vs onion vs Clean for entire afternoons and walk away exactly where they started. The argument is unwinnable as posed because none of them are the metric. They are all proxies for managing coupling, and nobody bothered to measure the metric.

Connascence is the case-file vocabulary because it gives the conversation rungs. “This service has too much coupling” is a vibe; “this service has Connascence of Position across an HTTP boundary, which would be a positional argument list across a network” is a refactoring instruction. Page-Jones gave the ladder in 19923 and Mark Richards and Neal Ford built the modern microservice frame on top of it: an architecture quantum is, definitionally, a unit of synchronous connascence.5 The vocabulary turned out to be load-bearing for a generation that never read the original.

Read the rule of locality literally. The same coupling that is fine inside one file is a disaster across module boundaries. Across services it is the architecture quantum reasserting itself and the result is a distributed monolith. Static is safer than dynamic, name is safer than type, type is safer than meaning: the ladder is the refactoring direction. Pair it with A2 Three-Tier Hoisting for the import-direction rule and A6 Bounded Contexts for the model boundary and the case file writes itself.

Copy a note and link

Grab this short comment and drop it into a PR comment or an LLM chat to prompt the right change.

Pick the architecture with the weaker coupling. Read every diff through Page-Jones's connascence ladder: static is safer than dynamic, name is safer than type, type is safer than meaning. The same coupling that is fine inside one file is a distributed monolith across services. Climb down the ladder where you can.

/tenet/coupling-first/A7
Copy for paste
§0c

AI eyes only

Rule: when two designs satisfy the requirement, pick the one with weaker connascence. Lower connascence wins over convention.

Reject: choosing the design with stronger coupling because it brings the next test faster. Reject: distributing connascence-of-meaning or connascence-of-position across a network or process boundary.

Generate: name the connascence type when proposing a refactor (CoN, CoT, CoM, CoP, CoA, CoE, CoTime, CoV, CoI). Choose the option that climbs the ladder downward.

Diagnostic: state the strongest connascence between the two units in one sentence. If you cannot name it, you do not understand the coupling and must not merge the change.

§0d

Why?

  • Connascence gives a code review a vocabulary with rungs. “Tightly coupled” is a vibe; “Connascence of Position across an HTTP boundary” is a refactoring instruction.
  • The Rule of Locality absorbs cohesion. Strong connascence inside one boundary is the definition of high cohesion. The same connascence between two services is the definition of a distributed monolith. One taxonomy, both jobs.
  • Static is safer than dynamic. Static connascence can be found by reading the source; dynamic connascence only shows at run time. That is why types, named identifiers and explicit signatures are the cheapest possible coupling, not bureaucratic overhead.
  • Most named architectural patterns are coupling-management techniques under another name. Strategy decouples policy from algorithm; Adapter decouples interface from implementation; Hexagonal decouples domain from I/O. Naming the coupling names the pattern.
  • Mark Richards and Neal Ford's architecture quantum, a unit of synchronous connascence, gives the cleanest microservice definition in print. If two pieces of code are connascent across the network, they are not two services.
  • Coupling is measurable. Robert C. Martin's instability metric I = Ce / (Ca + Ce), John Lakos's CCD/ACD physical-design metrics, and eslint's import/no-restricted-paths all read the dependency graph directly. The case file does not have to be philosophy.
  • Pairs with A6 Bounded Contexts. The connascence rule of locality applies at the boundary: cross-context imports are the smell and an Anti-Corruption Layer is the cure. The two tenets compose. Neither is enough on its own.
  • Coding agents are blind to coupling without a vocabulary. Put the connascence ladder in AGENTS.md and the model can name CoP, CoM, CoV in code review and propose the refactor that climbs down. Without the rungs, the agent treats coupling as a binary the way 2010 StackOverflow did.
The receipts
Origins, quoted passages, evidence, the strongest counter-argument and the reply.
§1

Origins

The principle is older than most acronyms. Larry Constantine introduced coupling and cohesion together at the 1968 National Symposium on Modular Programming, formalised in Stevens, Myers and Constantine's 1974 IBM Systems Journal paper “Structured Design”.1 Six rungs of coupling, seven rungs of cohesion: a single ranked taxonomy that told you which decompositions were better and which were worse. David Parnas's 1972 “On the Criteria To Be Used in Decomposing Systems into Modules” supplied the reasoning behind the taxonomy: modules earn their boundary by hiding a design decision. The cost of getting that wrong is paid in coupling.2

Meilir Page-Jones replaced the 1974 hierarchy with a sharper one in 1992. His paper “Comparing Techniques by Means of Encapsulation and Connascence” (CACM) introduced connascence: nine forms of coupling, graded along three properties, strength, locality, degree.3 The book-length treatment in What Every Programmer Should Know About Object-Oriented Design (Dorset House, 1995) gave us the vocabulary that has survived every shift in fashion since, and the ranking that goes with it: static connascence, which can be read off the source, is weaker than dynamic connascence, which only shows at run time.4 Static is safer than dynamic and the type system is safer than the runtime. Compile-time visibility is the cheapest possible coupling.

The modern frame is Mark Richards and Neal Ford's Fundamentals of Software Architecture (2020), where Page-Jones's taxonomy is rebuilt around the concept of an architecture quantum: a unit of synchronous connascence.5 If two pieces of code are connascent across a network boundary, they are not separate services. They are one service in two deployments. Vlad Khononov's Balancing Coupling in Software Design (2024) goes further: he stitches connascence to Constantine's 1974 hierarchy and adds his own Integration Strength model on top.6 Three primary sources, fifty years apart, all telling the same story: pick the architecture with the weaker coupling, and use a vocabulary that lets you tell which is which.

Robert C. Martin's instability metric (1994) is the package-level companion: I = Ce / (Ca + Ce), computed off the dependency graph, telling you which way the arrows ought to point.7 John Lakos's Large-Scale C++ Software Design (1996) added CCD, ACD and a whole physical-design metric set used to grade the levelisation of a package graph. Coupling has been measurable for thirty years. The canon's contribution is to insist it is the metric that matters.

§2

Quotes

Static connascences are considered to be weaker than dynamic connascences, since static connascences can be determined simply by examining the source code.

connascence.io · Strength

The effectiveness of a “modularization” is dependent upon the criteria used in dividing the system into modules.

David L. Parnas · CACM 15(12), 1972

Architecture quantum: An independently deployable artifact with high functional cohesion and synchronous connascence

Mark Richards & Neal Ford · Fundamentals of Software Architecture (2020)

Connascence feels more like a book exercise and is difficult to apply during the regular flow of test-driven development.

Kevin Rutherford · What happened to Connascence? (2024)
§3

Evidence

16 external sources, ranked by author authority. The first five are the canon; expand to see the rest, including the qualifiers and the named opposers. Each links out to its primary source.

  1. 01
    Stevens, Myers & Constantine · 1974
    The first published statement of the coupling/cohesion hierarchy. Coupling first as a design criterion is in print here.
  2. 02
    David L. Parnas · 1972
    Modules earn their boundary by hiding a design decision. The reasoning behind why some couplings cost more than others.
  3. 03
    Meilir Page-Jones · 1992
    Original journal paper introducing connascence: nine forms of coupling, three properties for grading severity, three rules of refactoring.
  4. 04
    Meilir Page-Jones · 1996
    The book-length treatment of connascence: its forms, and the strength, locality and degree that rank them.
  5. 05
    Mark Richards & Neal Ford · 2020
    Defines an architecture quantum as a unit of synchronous connascence. The modern microservice frame built on the 1992 taxonomy.
  1. 06
    Vlad Khononov · 2024
    Reconciles Page-Jones connascence with Constantine's 1974 module-coupling hierarchy. Adds Integration Strength as a working metric on top.
  2. 07
    Robert C. Martin · 1994
    Defines afferent / efferent coupling and the instability metric I = Ce / (Ca + Ce). Coupling at the package level, computable from the dependency graph.
  3. 08
    John Lakos · 1996
    Cumulative Component Dependency, Average Component Dependency, normalised CCD. A complete physical-design metric set used to grade levelisation of a package graph.
  4. 09
    John Ousterhout · 2018
    Names complexity as the master metric and reduces it to dependencies plus obscurity. Coupling is half the story. Obscurity is the other half.
  5. 10
    Robert C. Martin · 2017
    Restates the package-coupling principles (ADP, SDP, SAP). Coupling-direction is one rule among several. Cohesion principles (REP, CCP, CRP) live alongside.
  6. 11
    Sam Newman · 2021
    Classifies inter-service coupling as Domain / Pass-Through / Common / Content + Temporal. Treats coupling as the dominant axis without the universalist claim.
  7. 12
    MaibornWolff · 2019
    Practical refactoring guide built on Page-Jones's three properties (Strength, Locality, Degree). Translates each rung to working refactoring instructions.
  8. 13
    Khalil Stemmler · 2020
    Side-by-side reconciliation of Constantine and Page-Jones vocabularies. Useful for readers who hit both terms in the wild.
  9. 14
    Alistair Cockburn · 2005
    Architecture defined by coupling direction. Domain hexagon depends on no I/O; I/O depends on the domain. A pattern named after a coupling rule.
  10. 15
    Kevin Rutherford · 2024
    The honest steelman. Connascence felt like a book exercise during TDD-paced practice; “Explicit vs Implicit Coupling” survived because the team could remember it.
  11. 16
    Gregor Hohpe · 2018
    Multi-dimensional view: technology, location, data format, semantic, temporal, interaction style. A reminder that coupling is plural, not scalar.

Sixteen sources across the supports, qualifiers and opposers. Stevens, Myers & Constantine 1974, Parnas 1972, Page-Jones 1992 and 1996, and Richards & Ford 2020 are the spine. The qualifiers further down hold the metric-vs-vocabulary tension. The opposers hold the steelman the reply has to address. The honest argument is between the formalists and the pragmatists, not between the supporters and the sceptics.

§4

Examples

Viewing: TypeScript.
Avoid

Before CoP across two modules. Argument order is the contract.

Filerecord-hedgehog-sighting.ts
export function recordHedgehogSighting(
  lat: number, lng: number, weightG: number,
  lengthCm: number, observerId: string, observedAt: Date, microchipId: string
) {
  persist(lat, lng, weightG, lengthCm, observerId, observedAt, microchipId);
}
app/api/sightings/route.ts
recordHedgehogSighting(b.lat, b.lng, b.weightG, b.lengthCm, b.observerId, new Date(), b.chip);
scripts/import-historical-sightings.ts
recordHedgehogSighting(row[2], row[3], row[5], row[6], "legacy-import", row[1], row[0]);
Prefer

After CoN, locally contained. The names are the contract.

Filerecord-hedgehog-sighting.ts
export type HedgehogSightingInput = {
  lat: number; lng: number; weightG: number;
  lengthCm: number; observerId: string;
  observedAt: Date; microchipId: string;
}

export function recordHedgehogSighting(input: HedgehogSightingInput) { persist(input); }
app/api/sightings/route.ts
recordHedgehogSighting({ ...b, observedAt: new Date() });
scripts/import-historical-sightings.ts
recordHedgehogSighting(fromCsvRow(row));
§4b

Enforcement

Viewing: TypeScript.

Apply these rules in eslint.config.mjs. The full enforcement across every tenet lives on the implementation page.

RuleToolCatches
import/no-cycleeslint-plugin-importimport cycles in the dependency graph. Cycles are the architecture-quantum smell: connascence has crossed a boundary it should not have.
import/no-restricted-pathseslint-plugin-importimports that violate the rule of locality: a context reaching across a boundary it should be talking to via an Anti-Corruption Layer.
@typescript-eslint/max-paramstypescript-eslintlong positional argument lists. Connascence of Position; weaken to Connascence of Name with a parameter object.
sonarjs/no-identical-functionseslint-plugin-sonarjsfunctions with identical bodies. Connascence of Algorithm: two callers must agree on the same implementation.
sonarjs/no-duplicate-stringeslint-plugin-sonarjsmagic literals shared by multiple call sites. Connascence of Meaning; weaken to Connascence of Name with a constant.
@typescript-eslint/no-magic-numberstypescript-eslintuntyped numeric literals appearing inline. Magic numbers are the original Connascence of Meaning at file scope.
dependency-cruiser forbidden rulesdependency-cruiserpackage-graph violations as a CI step. Outputs the instability metric per module so you can see the I = Ce / (Ca + Ce) values directly.
eslint.config.mjsconfiguration snippet
import { defineConfig } from 'eslint/config';
import tseslint from 'typescript-eslint';
import importPlugin from 'eslint-plugin-import';
import sonarjs from 'eslint-plugin-sonarjs';

export default defineConfig({
  files: ['**/*.{ts,tsx}'],
  extends: [tseslint.configs.base],
  plugins: { import: importPlugin, sonarjs },
  rules: {
    'import/no-cycle': ['error', { maxDepth: 10 }],
    'import/no-restricted-paths': ['error', {
      zones: [
        {
          target: './src/lib',
          from: './src/app',
          message: 'Cross-context import, coupling rule of locality violated.',
        },
      ],
    }],
    'max-params': ['error', 3],
    'sonarjs/no-identical-functions': 'error',
    'sonarjs/no-duplicate-string': ['error', { threshold: 3 }],
    '@typescript-eslint/no-magic-numbers': ['error', {
      ignore: [-1, 0, 1],
      ignoreArrayIndexes: true,
      ignoreDefaultValues: true,
      enforceConst: true,
      ignoreEnums: true,
      ignoreNumericLiteralTypes: true,
      ignoreReadonlyClassProperties: true,
      ignoreTypeIndexes: true,
    }],
  }
});
§4c

AI rules

File.cursor/rules/a7-coupling-first.mdc
---
alwaysApply: true
---

## Prickles A7: Coupling First

Pick the architecture with the weaker coupling. Layers, patterns, frameworks are all proxies. The metric is coupling.

Read every diff through Page-Jones's connascence ladder. Static is safer than dynamic, name is safer than type, type is safer than meaning. Position is the smell that wants to become a parameter object.

Apply the rule of locality literally. The same coupling that is fine inside one file is a disaster across module boundaries. Across services it is a distributed monolith.

Refuse to merge a refactor that climbs the ladder upward (toward dynamic, away from static) without an explicit reason that the work cannot be done another way.

Repo layout, CI, and ESLint wiring for these paths live on /implementation, not repeated on every tenet.

§5

Counter-argument

Counter

The strongest steelman is Kevin Rutherford's.8 Rutherford coached connascence for years and watched it lose ground to plain English in TDD-paced practice. His 2022 retrospective is candid: the nine-rung Latin felt like a book exercise; Explicit vs Implicit Coupling survived because the team could use it during a refactor. The implication for “Coupling First” is sharp. The slogan is fine, the case-file vocabulary is academic and the academic vocabulary underperformed in the place it was supposed to do its work. If the rung labels never make it out of the dossier and into the diff, the ladder may as well not exist.

§6

Counter-argument retort

Reply

Cohesion is the obvious counter and the answer is: connascence absorbs it. The Rule of Locality, one of Page-Jones's three grading properties, is the cohesion argument restated in coupling vocabulary. Strong connascence inside one boundary is what cohesion looks like; the same connascence between two services ruins your week. Pick the coupling, set the boundary and you have done both jobs at once.

Kevin Rutherford's 2022 retrospective “What happened to Connascence?” is the honest pushback worth reading.8 Rutherford coached connascence for years and watched it lose ground to plain English, Explicit vs Implicit Coupling, because the Latin was too much to remember in the heat of a TDD cycle. His point stands. The fix is not to drop the taxonomy but to use the slogan up top and the taxonomy in the case file: read “coupling first” like a working developer reading “test first”, then climb the ladder when you need to name the rung.

The other reasonable objection is “coupling is one of many architectural metrics.” Performance, security, observability are real concerns with their own first principles. Granted. The honest weakening: most named architectural patterns are coupling-management techniques under another name. Strategy decouples policy from algorithm; Adapter decouples interface from implementation; Hexagonal decouples domain from I/O. The patterns book is a coupling textbook with the binding done in different colours.9 When two architectures look comparable, pick the one with the weaker coupling and you will be right more often than the toss of a coin would predict. That is why this tenet is a tenet.

A2 Three-Tier Hoisting already made the practical move: when reasonable patterns disagree, the tie-breaker is the connascence ladder. Static is safer than dynamic, name is safer than type, type is safer than meaning. The tenet's reply to every “but…” is the same: name the form, name the locality, name the degree, then choose.

§7

Notes

  1. [1]Stevens, Myers & Constantine: “Structured Design,” IBM Systems Journal 13(2), 1974, pp. 115-139. The first published statement of the coupling/cohesion hierarchy. Six rungs of coupling, seven rungs of cohesion, ranked weakest to strongest.
  2. [2]David L. Parnas: “On the Criteria To Be Used in Decomposing Systems into Modules,” CACM 15(12), Dec 1972, pp. 1053-1058. Information hiding as the criterion that explains why some couplings cost more than others.
  3. [3]Meilir Page-Jones: “Comparing Techniques by Means of Encapsulation and Connascence,” CACM 35(9), Sep 1992, pp. 147-151. The original journal paper. Nine forms of coupling, three properties for grading severity.
Disagree? Found a hole in the argument? Take issue with this tenet →
Last revised: 2026-10-23