# The structural domain

> This section covers the structural domain, which applies to all three cores and observes itself.

Page: Architecture · Principles
Canonical: https://banes-lab.com/software-architecture/principles#the-structural-domain

This section is stop 61 of 102 in the learning route. Previous: [05 - Execution joins the halves](https://banes-lab.com/software-architecture/principles/execution-joins-the-halves.md). Next: [07 - A tension has a mechanism](https://banes-lab.com/software-architecture/principles/a-tension-has-a-mechanism.md). It builds on [04 - Computation and resource](https://banes-lab.com/software-architecture/principles/computation-and-resource.md), [05 - Execution joins the halves](https://banes-lab.com/software-architecture/principles/execution-joins-the-halves.md).

This section covers the [structural](https://banes-lab.com/records/layer/structural-core.md) domain, which applies to all three cores and observes itself. Its principles are the classical ones, each paired with the practice the canon adds to it, as shown in [F1·a principle and practice](https://banes-lab.com/software-architecture/principles#the-structural-domain-panel-a).

### A principle and the practice that sharpens it

Classical principles are agreed at a level no check can reach, so what they mean in a given file is argued every time. Two reviewers agree that a module should have one responsibility and disagree about whether this one does, because responsibility was never derived from anything either of them could point at. A principle stated without a shape gives a reviewer nothing to point at, so the disagreement moves to what the principle means in this file, and that is the argument the pairing settles in advance.

For this reason a structural principle is a classical principle paired with the practice that makes it recognisable. What a principle means in a file is settled in advance, as a shape, rather than at each review. In practice, each classical principle is paired with the practice that makes it recognisable in a tree, and its violation is written as a shape a check can match. Where the pairing yields no shape, the principle is not yet held by anything.

To check this, take any structural principle you hold and state, in one sentence, what a violation of it looks like in a file. If the sentence names a shape, the principle has its practice. If it names an opinion, the pairing is still missing. A pairing sharpens a principle and never replaces it. The classical name still carries the intent a reader recognises, and the practice only says how that intent shows in a tree. A practice with no principle behind it is a house rule, and a principle with no practice is held by nothing.

### The pairs

[Separation of concerns](https://banes-lab.com/records/arch/separation-of-concerns.md) is paired with reasoning about the whole system, so one module holds one concern while the design is still read as one thing. Simplicity is paired with compression, because the simplest solution is a rule or a generator, never an enumeration, and a repeated shape is compressed by its type. A literal becomes a constant, a structure a composition, a behaviour one orchestrator, a fact one source. [Do not repeat yourself](https://banes-lab.com/records/arch/duplicate-code.md) is that compression named for the case of knowledge.

The [single responsibility principle](https://banes-lab.com/records/arch/single-responsibility.md) is derived from an invariant rather than a feature. The [open/closed principle](https://banes-lab.com/records/arch/open-closed.md) is met through few composable primitives, so extension arrives without editing what is tested. The [Liskov substitution principle](https://banes-lab.com/records/arch/liskov-substitution.md) makes substitutable parts order-independent. The [interface segregation principle](https://banes-lab.com/records/arch/interface-segregation.md) cuts an interface by usage, and the [dependency inversion principle](https://banes-lab.com/records/arch/dependency-inversion.md) addresses it by meaning rather than by location. [Composition over inheritance](https://banes-lab.com/records/arch/composition-over-inheritance.md) is the practice all five share, because a composed part can be replaced and an inherited one cannot.

[Code as data](https://banes-lab.com/records/arch/code-as-data.md) makes code, data and state one interchangeable structure, and [homoiconicity](https://banes-lab.com/records/arch/homoiconicity.md) is the degree to which a system has that property. One truth lives in versioned, queryable symbols, which is [single source of truth](https://banes-lab.com/records/arch/single-source-of-truth.md) with a location. Placement in a hierarchy reflects meaning, time is a logical sequence rather than a wall clock, and the system observes its own execution as data it can query, which is where [introspection](https://banes-lab.com/records/arch/introspection.md) and [observability](https://banes-lab.com/records/arch/observability.md) meet.

### Beneath the core

[Human factors](https://banes-lab.com/records/layer/human-factors.md) bound the whole by what a developer can hold. Related logic stays together, which is [high cohesion](https://banes-lab.com/records/arch/high-cohesion.md) read as a limit on attention. Complexity stays under a declared bound, and [bounded nesting depth](https://banes-lab.com/records/arch/bounded-nesting-depth.md) is one such bound made checkable. Uncertainty stops the work rather than passing silently. Internals are hidden but shipped with a live inspector, so [encapsulation](https://banes-lab.com/records/arch/encapsulation.md) is traded against debuggability at a point the developer chose.

[Evolution](https://banes-lab.com/records/layer/evolution-principles.md) says how the whole changes. Units are independent and swappable, with state protected before code. Features are added externally, through [extension points](https://banes-lab.com/records/arch/extension-points.md), with room left deliberately unspecified. Nothing is built that nothing needs, which refuses [speculative generality](https://banes-lab.com/records/arch/speculative-generality.md) and [premature abstraction](https://banes-lab.com/records/arch/premature-abstraction.md), and what the system will not do is written down in [architecture decision records](https://banes-lab.com/records/arch/architecture-decision-records.md) rather than remembered. [Evolutionary architecture](https://banes-lab.com/records/arch/evolutionary-architecture.md) with [fitness functions](https://banes-lab.com/records/arch/fitness-functions.md) is that domain held by checks rather than by review.

F1·a principle and practice

```mermaid
flowchart TB
classical["A classical principle · separation of concerns, simplicity, one responsibility"]
sharpened["The practice that sharpens it · the whole system in view, compression, an invariant"]
pair["One pair · the principle holds, the practice says how"]
human["Human factors · bounded by what a developer can hold"]
evolution["Evolution · state protected, room left, nothing built unneeded"]
classical --> pair
sharpened --> pair
pair --> human
pair --> evolution
```

## Links to

- [Structural Core](https://banes-lab.com/records/layer/structural-core.md)
- [Separation of Concerns](https://banes-lab.com/records/arch/separation-of-concerns.md)
- [Do Not Repeat Yourself (DRY)](https://banes-lab.com/records/arch/duplicate-code.md)
- [Single Responsibility Principle (SRP)](https://banes-lab.com/records/arch/single-responsibility.md)
- [Open/Closed Principle (OCP)](https://banes-lab.com/records/arch/open-closed.md)
- [Liskov Substitution Principle (LSP)](https://banes-lab.com/records/arch/liskov-substitution.md)
- [Interface Segregation Principle (ISP)](https://banes-lab.com/records/arch/interface-segregation.md)
- [Dependency Inversion Principle (DIP)](https://banes-lab.com/records/arch/dependency-inversion.md)
- [Composition Over Inheritance](https://banes-lab.com/records/arch/composition-over-inheritance.md)
- [Code as Data](https://banes-lab.com/records/arch/code-as-data.md)
- [Homoiconicity](https://banes-lab.com/records/arch/homoiconicity.md)
- [Single Source of Truth](https://banes-lab.com/records/arch/single-source-of-truth.md)
- [Introspection](https://banes-lab.com/records/arch/introspection.md)
- [Observability](https://banes-lab.com/records/arch/observability.md)
- [Human Factors](https://banes-lab.com/records/layer/human-factors.md)
- [High Cohesion](https://banes-lab.com/records/arch/high-cohesion.md)
- [Bounded Nesting Depth](https://banes-lab.com/records/arch/bounded-nesting-depth.md)
- [Encapsulation](https://banes-lab.com/records/arch/encapsulation.md)
- [Evolution Principles](https://banes-lab.com/records/layer/evolution-principles.md)
- [Extension Points](https://banes-lab.com/records/arch/extension-points.md)
- [Speculative Generality](https://banes-lab.com/records/arch/speculative-generality.md)
- [Premature Abstraction](https://banes-lab.com/records/arch/premature-abstraction.md)
- [Architecture Decision Records (ADR)](https://banes-lab.com/records/arch/architecture-decision-records.md)
- [Evolutionary Architecture](https://banes-lab.com/records/arch/evolutionary-architecture.md)
- [Fitness Functions](https://banes-lab.com/records/arch/fitness-functions.md)
