# Anti-patterns

> Every principle in this category is listed as a record.

Page: Ontology · Principles
Canonical: https://banes-lab.com/ontology#architecture-category-anti-patterns

Listed in [Ontology · Principles](https://banes-lab.com/api/pages/ontology/principles.md), before [Domain Architecture](https://banes-lab.com/ontology/principles/architecture-category-domain-architecture.md).

Every principle in this category is listed as a record. Each record carries its kind, its severity, the scopes it applies at and the layer it lives in, then the edge relations that join it to other records, the records that point back at it, the contracts that answer to it and the tensions it takes part in. The descriptors say how it is violated, detected, measured, repaired and enforced. Where the record carries one, an exemplar shows the shape before and after the principle is applied.

Relations diagram

The relations inside this category.

```mermaid
flowchart LR
n_big_ball_of_mud["Big Ball of Mud"]
n_god_object["God Object"]
n_concrete_coupling["Concrete Coupling"]
n_schema_drift["Schema Drift"]
n_implicit_contract["Implicit Contract"]
n_hardcoded_configuration["Hardcoded Configuration"]
n_shared_mutable_state["Shared Mutable State"]
n_boundary_leakage["Boundary Leakage"]
n_manual_only_governance["Manual-Only Governance"]
n_opaque_runtime_behavior["Opaque Runtime Behavior"]
n_unowned_risk["Unowned Risk"]
n_unobservable_failure["Unobservable Failure"]
n_unversioned_breaking_change["Unversioned Breaking Change"]
n_distributed_monolith["Distributed Monolith"]
n_shotgun_surgery["Shotgun Surgery"]
n_divergent_change["Divergent Change"]
n_feature_envy["Feature Envy"]
n_inappropriate_intimacy["Inappropriate Intimacy"]
n_message_chain["Message Chain"]
n_middle_man["Middle Man"]
n_data_clumps["Data Clumps"]
n_primitive_obsession["Primitive Obsession"]
n_stringly_typed_programming["Stringly Typed Programming"]
n_boolean_trap["Boolean Trap"]
n_long_parameter_list["Long Parameter List"]
n_magic_value["Magic Value"]
n_speculative_generality["Speculative Generality"]
n_premature_abstraction["Premature Abstraction"]
n_over_abstraction["Over-Abstraction"]
n_golden_hammer["Golden Hammer"]
n_pattern_cargo_cult["Pattern Cargo Cult"]
n_lava_flow["Lava Flow"]
n_zombie_code["Zombie Code"]
n_temporal_coupling["Temporal Coupling"]
n_hidden_side_effect["Hidden Side Effect"]
n_action_at_a_distance["Action at a Distance"]
n_ambient_context["Ambient Context"]
n_inconsistent_error_model["Inconsistent Error Model"]
n_exception_control_flow["Exception Control Flow"]
n_null_semantics_drift["Null Semantics Drift"]
n_anemic_domain_model["Anemic Domain Model"]
n_transaction_script_sprawl["Transaction Script Sprawl"]
n_fat_controller["Fat Controller"]
n_repository_dump["Repository Dump"]
n_utility_dump["Utility Dump"]
n_framework_leakage["Framework Leakage"]
n_vendor_lock_in_leakage["Vendor Lock-In Leakage"]
n_circular_dependency["Circular Dependency"]
n_cyclic_deployment_dependency["Cyclic Deployment Dependency"]
n_synchronous_chain_trap["Synchronous Chain Trap"]
n_chatty_interface["Chatty Interface"]
n_n_plus_one_query["N Plus One Query"]
n_cache_poisoning_by_design["Cache Poisoning by Design"]
n_retry_storm["Retry Storm"]
n_timeout_omission["Timeout Omission"]
n_missing_backpressure["Missing Backpressure"]
n_silent_data_corruption["Silent Data Corruption"]
n_lost_update["Lost Update"]
n_dual_write["Dual Write"]
n_read_your_writes_violation["Read-Your-Writes Violation"]
n_security_theater["Security Theater"]
n_authorization_scattering["Authorization Scattering"]
n_secret_sprawl["Secret Sprawl"]
n_personal_data_oversharing["Personal Data Oversharing"]
n_observability_noise["Observability Noise"]
n_log_as_control_flow["Log-as-Control-Flow"]
n_manual_runbook_dependency["Manual Runbook Dependency"]
n_big_bang_release["Big-Bang Release"]
n_irreversible_migration["Irreversible Migration"]
n_big_upfront_frozen_architecture["Big-Upfront Frozen Architecture"]
n_architecture_astronaut["Architecture Astronaut"]
n_feature_only_design["Feature-Only Design"]
n_test_pyramid_inversion["Test Pyramid Inversion"]
n_mock_mirage["Mock Mirage"]
n_flaky_test_normalization["Flaky Test Normalization"]
n_prompt_sprawl["Prompt Sprawl"]
n_ungrounded_content["Ungrounded Content"]
n_model_version_ambiguity["Model Version Ambiguity"]
```

### Big Ball of Mud

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [state_transaction](https://banes-lab.com/records/force/state-transaction.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a system has no discernible boundaries, so any part can depend on and change any other.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Modularity](https://banes-lab.com/records/architecture/modularity.md), [Component-Based Architecture](https://banes-lab.com/records/architecture/component-based-architecture.md)

Contracts
[<Architecture Anti-Pattern>](https://banes-lab.com/records/algorithms/architecture-anti-pattern.md)

Violated by
Allow boundaries to remain implicit, permit unrestricted dependencies, mix concerns freely, share mutable state broadly, and accumulate changes without architectural segmentation.

Detected by
[cyclic_dependencies](https://banes-lab.com/records/architecture/circular-dependency.md), high_graph_density, unowned_modules, cross_layer_imports, large_change_blast_radius

Measured by
dependency-cycle count, graph density, share of modules without an owner

Refactored by
define_boundaries, split_modules, enforce_dependency_rules, assign_ownership, add_fitness_functions

Enforced by
dependency rules, architecture fitness functions, module ownership map

Before

```typescript
function handle(req) {
const foo = db.query(req.body.sql);
render(foo); email(foo); audit(foo); cache(foo);
}
```

After

```typescript
class CreateFoo {
constructor(private readonly foos: FooRepository, private readonly events: EventPublisher) {}
execute(input: CreateFooInput) { const foo = Foo.create(input); this.foos.save(foo); this.events.publish(fooCreated(foo)); }
}
```

How it is checked

Checked by
dependency rules, architecture fitness functions, module ownership map

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Big Ball of Mud](https://banes-lab.com/records/architecture/big-ball-of-mud.md)

### God Object

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [semantic_consistency](https://banes-lab.com/records/force/semantic-consistency.md), [domain_boundary](https://banes-lab.com/records/force/domain-boundary.md), [control_coordination](https://banes-lab.com/records/force/control-coordination.md)
- Aliases: Blob Class
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which one object accumulates unrelated responsibilities and becomes the default place for every change.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Single Responsibility Principle (SRP)](https://banes-lab.com/records/architecture/single-responsibility.md), [High Cohesion](https://banes-lab.com/records/architecture/high-cohesion.md)

Distinct from
[Divergent Change](https://banes-lab.com/records/architecture/divergent-change.md): A god object is one object holding many responsibilities, while divergent change is the symptom of one module changing for many reasons.

Distinct from
[Shotgun Surgery](https://banes-lab.com/records/architecture/shotgun-surgery.md): A god object concentrates responsibilities in one place, while shotgun surgery scatters one responsibility across many.

Distinct from
[Utility Dump](https://banes-lab.com/records/architecture/utility-dump.md): A god object is a domain object that absorbs every change, while a utility dump is a generic helper module that no one owns.

Violated by
Centralize unrelated responsibilities into one object, route unrelated behavior through it, accumulate state and dependencies, and make the object the default modification point.

Detected by
large_class, many_unrelated_methods, many_dependencies, high_fan_in, multiple_reasons_to_change

Measured by
methods and dependencies per class, [fan-in](https://banes-lab.com/records/lexicon/fan-in.md), distinct reasons to change

Refactored by
extract_class, split_responsibilities, move_method, extract_domain_service, introduce_facade_only_if_boundary_needed

Enforced by
class size and responsibility limits in lint, [design review](https://banes-lab.com/records/architecture/design-review.md)

Before

```typescript
class FooManager {
createFoo() {} priceFoo() {} renderFoo() {} emailFoo() {} auditFoo() {} shipFoo() {}
}
```

After

```typescript
class FooFactory { create(input: CreateFooInput): Foo {} }
class FooPricer { price(foo: Foo): Money {} }
class FooShipper { ship(foo: Foo): void {} }
```

How it is checked

Checked by
class size and responsibility limits in lint, design review

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[God Object](https://banes-lab.com/records/architecture/god-object.md)

### Concrete Coupling

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which high-level policy depends directly on concrete implementations instead of on abstractions.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Interface-Based Design](https://banes-lab.com/records/architecture/interface-based-design.md), [Abstraction](https://banes-lab.com/records/architecture/abstraction.md), [Replaceability](https://banes-lab.com/records/architecture/replaceability.md)

Distinct from
[Middle Man](https://banes-lab.com/records/architecture/middle-man.md): Concrete coupling depends on an implementation instead of an abstraction, while a middle man is a layer of indirection that adds nothing.

Violated by
Let high-level policy depend directly on low-level implementations, vendor APIs, framework classes, or concrete constructors, then spread those concrete assumptions across the core.

Detected by
domain_imports_infrastructure, vendor_sdk_in_core, new_dependency_inside_business_logic, missing_interface_boundary

Measured by
concrete infrastructure imports in core modules

Refactored by
extract_interface, introduce_port, extract_adapter, inject_dependency, apply_DIP

Enforced by
import rules that forbid infrastructure in the core, architecture tests

Refused by rules
concrete-coupling

Before

```typescript
class FooService {
private readonly store = new SqlFooStore();
}
```

After

```typescript
class FooService {
constructor(private readonly store: FooStore) {}
}
```

How it is checked

Checked by
import rules that forbid infrastructure in the core, architecture tests

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Concrete Coupling](https://banes-lab.com/records/architecture/concrete-coupling.md)

### Schema Drift

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [security_governance](https://banes-lab.com/records/force/security-governance.md), [model_governance](https://banes-lab.com/records/force/model-governance.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which the producers, consumers and stores of one payload evolve its shape independently until its meaning diverges.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Data Contract](https://banes-lab.com/records/architecture/data-contract.md), [Canonical Schema](https://banes-lab.com/records/architecture/canonical-schema.md)

Violated by
Allow producers, consumers, storage models, and documentation to evolve independently without versioned schema governance, then let payload meaning diverge over time.

Detected by
schema_diff_failure, missing_schema_registry, consumer_parse_errors, undocumented_field_changes, nullability_mismatch

Measured by
schema diff failures and consumer parse errors per release

Refactored by
define_schema_contract, version_schema, add_compatibility_tests, centralize_schema_registry, validate_payloads

Enforced by
schema registry, compatibility tests in the build

Before

```typescript
type FooApi = { id: string; label: string };
type FooDb = { id: string; name: string; extra: string };
```

After

```typescript
const FooSchema = schema({ id: fooIdSchema, name: nonEmptyString });
type Foo = Infer<typeof FooSchema>;
fooApi.use(FooSchema);
fooDb.use(FooSchema);
```

How it is checked

Checked by
schema registry, compatibility tests in the build

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Schema Drift](https://banes-lab.com/records/architecture/schema-drift.md)

### Implicit Contract

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [causality_ordering](https://banes-lab.com/records/force/causality-ordering.md)
- Aliases: Implicit Payloads
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a boundary's assumptions, including the shape and meaning of the data it passes, live in behavior, naming or ordering rather than in a declared contract.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Explicit Contracts](https://banes-lab.com/records/architecture/explicit-contracts.md)

Violated by
Encode assumptions in code behavior, naming, ordering, timing, side effects, or undocumented payload shapes instead of declaring them as explicit contracts.

Detected by
public_API_without_schema, undocumented_side_effect, dynamic_map_boundary, tests_depend_on_internal_behavior, tribal_knowledge_required

Measured by
public operations without a declared schema

Refactored by
add_explicit_contract, define_preconditions, define_postconditions, add_schema, add_contract_tests

Enforced by
contract tests, schema validation at public boundaries

Before

```typescript
function saveFoo(foo) { return db.insert(foo); }
```

After

```typescript
interface Foo { id: FooId; name: NonEmptyString; }
function saveFoo(foo: Foo): Promise<void> { return fooStore.save(foo); }
```

How it is checked

Checked by
contract tests, schema validation at public boundaries

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Implicit Contract](https://banes-lab.com/records/architecture/implicit-contract.md)

### Hardcoded Configuration

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [semantic_consistency](https://banes-lab.com/records/force/semantic-consistency.md), [state_transaction](https://banes-lab.com/records/force/state-transaction.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which environment, credential or policy values are written into code instead of being supplied as configuration.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Configuration Externalization](https://banes-lab.com/records/architecture/configuration-externalization.md), [Declarative Configuration](https://banes-lab.com/records/architecture/declarative-configuration.md)

Violated by
Embed environment, path, credential, feature, service endpoint, or policy values directly into code, then duplicate those assumptions across runtime contexts.

Detected by
hardcoded_URL, hardcoded_path, hardcoded_secret, environment_branching_in_code, duplicated_config_literal

Measured by
configuration literals and secrets found in source

Refactored by
externalize_configuration, add_config_schema, centralize_config_source, validate_environment, remove_secret_from_code

Enforced by
configuration and secret scans, a configuration schema validated at startup

Before

```typescript
const client = new FooClient("https://foo.prod.example", "sk_live_abc123");
```

After

```typescript
const config = FooConfigSchema.parse({ url: process.env.FOO_URL, key: process.env.FOO_KEY });
const client = new FooClient(config);
```

How it is checked

Checked by
configuration and secret scans, a configuration schema validated at startup

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Hardcoded Configuration](https://banes-lab.com/records/architecture/hardcoded-configuration.md)

### Shared Mutable State

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [state_transaction](https://banes-lab.com/records/force/state-transaction.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which writable state is shared across modules with no owner and no synchronization.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Immutability](https://banes-lab.com/records/architecture/immutability.md), [State Isolation](https://banes-lab.com/records/architecture/state-isolation.md)

Violated by
Expose writable state across modules, allow multiple actors to mutate it, omit ownership and synchronization, and let behavior depend on mutation order.

Detected by
global_mutable_object, public_mutable_fields, shared_cache_without_policy, race_condition, order_dependent_tests

Measured by
writable state reachable from more than one module, race-detector findings

Refactored by
encapsulate_state, assign_owner, make_immutable, add_transaction_boundary, apply_concurrency_control

Enforced by
immutability and visibility lint rules, concurrency tests

Before

```typescript
let currentFoo = null;
function setFoo(f) { currentFoo = f; }
function useFoo() { return currentFoo.name; }
```

After

```typescript
class FooContext {
constructor(private readonly foo: Foo) {}
name() { return this.foo.name; }
}
```

How it is checked

Checked by
immutability and visibility lint rules, concurrency tests

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Shared Mutable State](https://banes-lab.com/records/architecture/shared-mutable-state.md)

### Boundary Leakage

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [model_governance](https://banes-lab.com/records/force/model-governance.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which internal, persistence or vendor types cross an architectural boundary.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Explicit Boundaries](https://banes-lab.com/records/architecture/explicit-boundaries.md)

Violated by
Permit internal models, infrastructure types, persistence structures, or private module APIs to cross intended architectural boundaries.

Detected by
internal_package_imported_externally, database_entity_exposed_as_API, vendor_type_in_domain, private_module_used_by_other_module

Measured by
internal types exposed across boundaries

Refactored by
restrict_exports, introduce_DTO, add_adapter, add_facade, enforce_import_rules

Enforced by
export and import restrictions, boundary architecture tests

Before

```typescript
app.get("/foo/:id", async (req, res) => res.json(await ormFoo.findByPk(req.params.id)));
```

After

```typescript
app.get("/foo/:id", async (req, res) => res.json(toFooDto(await getFoo.execute(req.params.id))));
```

How it is checked

Checked by
export and import restrictions, boundary architecture tests

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Boundary Leakage](https://banes-lab.com/records/architecture/boundary-leakage.md)

### Manual-Only Governance

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md), [security_governance](https://banes-lab.com/records/force/security-governance.md)
- Aliases: Document-Only Policy
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which architecture rules or security policies exist only in documents or in reviewers' memory, with no executable check, so they drift from what the system does.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Policy as Code](https://banes-lab.com/records/architecture/policy-as-code.md)

Contracts
[Quality Governance Loop](https://banes-lab.com/records/algorithms/quality-governance-loop.md)

Violated by
Encode architecture rules in documents, meetings, or reviewer memory without executable checks, metrics, or automated enforcement.

Detected by
rule_exists_only_in_docs, no_CI_gate, reviewer_specific_enforcement, repeated_same_violation, missing_fitness_function

Measured by
stated rules without an executable check, repeat violations of one rule

Refactored by
create_fitness_function, add_static_check, add_policy_as_code, add_architecture_test, track_rule_metrics

Enforced by
a rule-coverage check that requires every stated rule to name its executable gate

Before

```typescript
const CONVENTION = "remember to prefix every foo id with foo_";
```

After

```typescript
export const rule = { id: "valid-foo-id", check: (id: string) => id.startsWith("foo_") };
```

How it is checked

Checked by
a rule-coverage check that requires every stated rule to name its executable gate

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Manual-Only Governance](https://banes-lab.com/records/architecture/manual-only-governance.md)

### Opaque Runtime Behavior

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [runtime_extensibility](https://banes-lab.com/records/force/runtime-extensibility.md), [metaprogramming_modeling](https://banes-lab.com/records/force/metaprogramming-modeling.md)
- Aliases: Opaque Runtime
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which runtime behavior emerges from hidden reflection, registration or binding that nothing reports, so the runtime's structure and state cannot be inspected.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Introspection](https://banes-lab.com/records/architecture/introspection.md)

Violated by
Let runtime behavior emerge from hidden reflection, implicit registration, undocumented configuration, side effects, or untraced dynamic binding.

Detected by
dynamic_binding_without_manifest, missing_startup_report, unlogged_plugin_loading, implicit_reflection_scan, untraceable_side_effect

Measured by
dynamic bindings without a manifest entry

Refactored by
add_manifest, log_binding_decisions, emit_runtime_topology, add_capability_declaration, add_discovery_validation

Enforced by
manifest validation, a startup report that lists every binding

Before

```typescript
function processFoo(foo) { doWork(foo); }
```

After

```typescript
function processFoo(foo: Foo) {
logger.info("foo.process.start", { fooId: foo.id });
const result = doWork(foo);
logger.info("foo.process.done", { fooId: foo.id, outcome: result.status });
}
```

How it is checked

Checked by
manifest validation, a startup report that lists every binding

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Opaque Runtime Behavior](https://banes-lab.com/records/architecture/opaque-runtime-behavior.md)

### Unowned Risk

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [architecture_evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- Aliases: Unknown/Unowned Risk
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a risk is never identified, or is identified and has no owner, severity, mitigation or review date.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Risk Management](https://banes-lab.com/records/architecture/risk-management.md)

Violated by
Identify a risk without assigning owner, severity, mitigation, review date, acceptance status, or escalation path.

Detected by
risk_without_owner, ADR_missing_consequence_owner, security_finding_unassigned, known_gap_without_due_date, accepted_risk_without_expiry

Measured by
risks without an owner, reviews past their date

Refactored by
assign_owner, classify_severity, define_mitigation, record_acceptance, schedule_review

Enforced by
a risk register whose entries are validated for owner, severity and review date

Before

```typescript
risks.push({ title: "the foo store has no backup" });
```

After

```typescript
risks.push({ title: "the foo store has no backup", owner: "storage team", severity: "high", mitigation: "nightly snapshot", reviewBy: "2026-12-01" });
```

How it is checked

Checked by
a risk register whose entries are validated for owner, severity and review date

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Unowned Risk](https://banes-lab.com/records/architecture/unowned-risk.md)

### Unobservable Failure

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md)
- Aliases: Opaque System
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which an operation can fail without leaving a log, metric, trace or error contract.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Observability](https://banes-lab.com/records/architecture/observability.md)

Violated by
Permit operations to fail without structured logs, metrics, alerts, traces, audit records, or user-visible error contracts.

Detected by
empty_catch, swallowed_exception, missing_error_log, no_alert_on_critical_path, missing_trace_span, missing_audit_record

Measured by
swallowed exceptions, critical paths without error telemetry

Refactored by
add_error_boundary, emit_structured_log, add_metric, add_alert, add_trace_span, add_audit_log

Enforced by
lint rules against empty and swallowing catch blocks, telemetry coverage checks

Before

```typescript
try { await ship(foo); } catch { }
```

After

```typescript
try { await ship(foo); } catch (error) { logger.error("foo.ship.failed", error); metrics.increment("foo.ship.failure"); throw new ShipFailedError(foo.id); }
```

How it is checked

Checked by
lint rules against empty and swallowing catch blocks, telemetry coverage checks

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Unobservable Failure](https://banes-lab.com/records/architecture/unobservable-failure.md)

### Unversioned Breaking Change

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [event_messaging](https://banes-lab.com/records/force/event-messaging.md), [architecture_evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a public contract changes incompatibly without a version, a deprecation path or a compatibility test.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Consumer-Driven Contracts](https://banes-lab.com/records/architecture/consumer-driven-contracts.md)

Violated by
Change a public API, schema, event, protocol, behavior, or package contract incompatibly without version bump, deprecation path, compatibility test, or migration notice.

Detected by
API_diff_breaking, schema_field_removed, type_narrowed, event_semantics_changed, no_version_bump, no_deprecation_window

Measured by
breaking diffs released without a version bump

Refactored by
bump_version, add_compatibility_adapter, deprecate_gradually, add_contract_tests, publish_migration_guide

Enforced by
API and schema diff gates in the release pipeline

Before

```typescript
app.get("/foo", () => ({ label: foo.name }));
```

After

```typescript
app.get("/v2/foo", () => ({ name: foo.name }));
app.get("/v1/foo", () => ({ label: foo.name }));
```

How it is checked

Checked by
API and schema diff gates in the release pipeline

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Unversioned Breaking Change](https://banes-lab.com/records/architecture/unversioned-breaking-change.md)

### Distributed Monolith

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [state_transaction](https://banes-lab.com/records/force/state-transaction.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which services are deployed separately but still share data, transactions and release cycles.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Microservices](https://banes-lab.com/records/architecture/microservices.md)

Violated by
Split deployment units without splitting data ownership, transaction boundaries, failure isolation, contracts, or autonomous release capability.

Detected by
[shared_database](https://banes-lab.com/records/lexicon/shared-database.md), cross_service_transactions, lockstep_deployments, deep_sync_call_chain, shared_business_logic_package, consumer_breakage_on_service_change

Measured by
shared databases, lockstep deployments, cross-service transactions

Refactored by
own_data_per_service, define_service_contracts, introduce_events, add_outbox, split_bounded_context, enable_independent_deployment

Enforced by
service-ownership rules, contract tests, independent-deployment checks

Before

```typescript
async function createFoo(foo) {
await http.post("bar-service/validate", foo);
await http.post("baz-service/price", foo);
await http.post("qux-service/save", foo);
}
```

After

```typescript
async function createFoo(input: CreateFooInput) {
const foo = Foo.create(input);
await fooStore.save(foo);
await outbox.append(fooCreated(foo));
}
```

How it is checked

Checked by
service-ownership rules, contract tests, independent-deployment checks

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Distributed Monolith](https://banes-lab.com/records/architecture/distributed-monolith.md)

### Shotgun Surgery

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which one responsibility is scattered so that a single change needs edits in many files.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[High Cohesion](https://banes-lab.com/records/architecture/high-cohesion.md)

Violated by
Scatter one conceptual responsibility across many files so one change requires many coordinated edits.

Detected by
same_change_touches_many_files, repeated_commit_cochanges, duplicated_rule_fragments

Measured by
files touched per logical change, co-change frequency

Refactored by
centralize_rule, extract_module, move_behavior_to_owner, add_single_source_of_truth

Enforced by
duplication detection, change-coupling review

Before

```typescript
const taxA = value * 0.2;
const taxB = other * 0.2;
const taxC = more * 0.2;
```

After

```typescript
const FOO_TAX_RATE = 0.2;
function taxFoo(value: number) { return value * FOO_TAX_RATE; }
```

How it is checked

Checked by
duplication detection, change-coupling review

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Shotgun Surgery](https://banes-lab.com/records/architecture/shotgun-surgery.md)

### Divergent Change

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which one module changes for many unrelated reasons.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Single Responsibility Principle (SRP)](https://banes-lab.com/records/architecture/single-responsibility.md)

Violated by
Place unrelated responsibilities in the same module so unrelated change reasons repeatedly modify one artifact.

Detected by
unrelated_commits_touch_same_file, mixed_methods, mixed_dependencies

Measured by
distinct reasons to change per module in the change history

Refactored by
split_module, extract_class, separate_concerns, move_method

Enforced by
module cohesion limits, [design review](https://banes-lab.com/records/architecture/design-review.md)

Before

```typescript
class Foo {
renderHtml() {} saveToSql() {} sendEmail() {} parseCsv() {}
}
```

After

```typescript
class Foo {}
class FooView { render(foo: Foo): string {} }
class FooStore { save(foo: Foo): Promise<void> {} }
```

How it is checked

Checked by
module cohesion limits, design review

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Divergent Change](https://banes-lab.com/records/architecture/divergent-change.md)

### Feature Envy

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which one module mostly works on another module's data instead of its own.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Encapsulation](https://banes-lab.com/records/architecture/encapsulation.md)

Violated by
Let one module repeatedly inspect or manipulate another module’s data instead of moving behavior to the data owner.

Detected by
many_getters_from_other_object, logic_using_foreign_fields, domain_rule_outside_owner

Measured by
foreign field accesses per method

Refactored by
move_method, encapsulate_state, add_domain_behavior, introduce_service_boundary

Enforced by
coupling analysis in lint, [design review](https://banes-lab.com/records/architecture/design-review.md)

Before

```typescript
function totalFoo(bar: Bar) { return bar.items.reduce((s, i) => s + i.price * i.qty, 0); }
```

After

```typescript
class Bar { total(): Money { return this.items.reduce((s, i) => s + i.subtotal(), 0); } }
```

How it is checked

Checked by
coupling analysis in lint, design review

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Feature Envy](https://banes-lab.com/records/architecture/feature-envy.md)

### Inappropriate Intimacy

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which modules depend on each other's internal structure or private state.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md)

Distinct from
[Message Chain](https://banes-lab.com/records/architecture/message-chain.md): Inappropriate intimacy reads another module's internals, while a message chain navigates a chain of public references.

Violated by
Allow modules or classes to rely on each other’s internals, private structure, lifecycle, or undocumented state.

Detected by
friend-like access, private API usage, tests_reach_internals, internal_package_import

Measured by
private-member accesses across modules

Refactored by
hide_internal, introduce_public_contract, add_facade, restrict_exports

Enforced by
visibility and export rules, tests limited to public interfaces

Before

```typescript
bar.foo._internalState.status = "ready";
```

After

```typescript
bar.foo.markReady();
```

How it is checked

Checked by
visibility and export rules, tests limited to public interfaces

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Inappropriate Intimacy](https://banes-lab.com/records/architecture/inappropriate-intimacy.md)

### Message Chain

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [event_messaging](https://banes-lab.com/records/force/event-messaging.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a client navigates a chain of objects to reach the behavior it needs.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md)

Violated by
Require clients to traverse a chain of objects to reach behavior or data, exposing internal object graph structure.

Detected by
a.getB().getC().doX, deep_property_access, repeated_navigation_paths

Measured by
member-access chain depth at call sites

Refactored by
hide_delegate, introduce_facade_method, move_behavior_to_owner

Enforced by
a lint rule on member-access chain depth

Before

```typescript
const city = foo.getOwner().getAddress().getCity().getName();
```

After

```typescript
const city = foo.ownerCityName();
```

How it is checked

Checked by
a lint rule on member-access chain depth

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Message Chain](https://banes-lab.com/records/architecture/message-chain.md)

### Middle Man

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md), [control_coordination](https://banes-lab.com/records/force/control-coordination.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a module delegates almost every call without adding behavior of its own.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Abstraction](https://banes-lab.com/records/architecture/abstraction.md)

Violated by
Insert a module that delegates almost everything without adding policy, abstraction, validation, orchestration, or simplification.

Detected by
thin_methods_only_delegate, low_logic_density, one_to_one_wrapper_methods

Measured by
share of methods that only delegate

Refactored by
remove_layer, inline_delegate, promote_to_real_facade_if_boundary_needed

Enforced by
delegation-ratio analysis, [design review](https://banes-lab.com/records/architecture/design-review.md)

Before

```typescript
class FooService {
save(foo: Foo) { return this.store.save(foo); }
find(id: FooId) { return this.store.find(id); }
}
```

After

```typescript
const fooStore: FooStore = new SqlFooStore();
```

How it is checked

Checked by
delegation-ratio analysis, design review

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Middle Man](https://banes-lab.com/records/architecture/middle-man.md)

### Data Clumps

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which the same group of values travels together without being named as one type.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Value Object](https://banes-lab.com/records/architecture/value-object.md)

Distinct from
[Long Parameter List](https://banes-lab.com/records/architecture/long-parameter-list.md): Data clumps are one group of values travelling together unnamed, while a long parameter list is one signature with too many parameters of any kind.

Violated by
Pass the same group of fields together repeatedly without naming the group as a value object or contract.

Detected by
same_parameters_repeated, same_fields_appear_together, DTO_shape_duplicated

Measured by
repeated parameter groups across signatures

Refactored by
introduce_value_object, add_DTO, name_concept, validate_as_group

Enforced by
duplicate parameter-group detection in lint

Before

```typescript
function shipFoo(street: string, city: string, zip: string, country: string) {}
```

After

```typescript
interface Address { street: string; city: string; zip: string; country: string; }
function shipFoo(address: Address) {}
```

How it is checked

Checked by
duplicate parameter-group detection in lint

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Data Clumps](https://banes-lab.com/records/architecture/data-clumps.md)

### Primitive Obsession

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md), [domain_boundary](https://banes-lab.com/records/force/domain-boundary.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which domain concepts are held in raw primitives with no type or validation.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Value Object](https://banes-lab.com/records/architecture/value-object.md)

Distinct from
[Data Clumps](https://banes-lab.com/records/architecture/data-clumps.md): Primitive obsession holds one concept in a raw primitive, while data clumps are several values that belong together as one type.

Distinct from
[Long Parameter List](https://banes-lab.com/records/architecture/long-parameter-list.md): Primitive obsession is about the type of one value, while a long parameter list is about the number of parameters in one signature.

Violated by
Represent meaningful domain concepts as raw strings, numbers, booleans, or maps without type, validation, or behavior.

Detected by
many_string_ids, repeated_validation, boolean_flags, magic_values

Measured by
domain concepts held in primitive types

Refactored by
introduce_value_object, narrow_type, add_enum, encapsulate_validation

Enforced by
type checks and a lint rule against primitive-typed domain identifiers

Before

```typescript
function transfer(fooId: string, amount: number, currency: string) {}
```

After

```typescript
class Money { constructor(readonly amount: number, readonly currency: Currency) {} }
function transfer(fooId: FooId, money: Money) {}
```

How it is checked

Checked by
type checks and a lint rule against primitive-typed domain identifiers

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Primitive Obsession](https://banes-lab.com/records/architecture/primitive-obsession.md)

### Stringly Typed Programming

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [architecture_evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which states, types or permissions are encoded as unchecked strings.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Type Safety](https://banes-lab.com/records/architecture/type-safety.md)

Violated by
Encode behavior, types, states, permissions, or protocols as unchecked strings.

Detected by
string_mode_switch, repeated_string_constants, string_permissions, string_status_values

Measured by
string comparisons against values of a closed set

Refactored by
add_enum, add_discriminated_union, centralize_constants, schema_validate

Enforced by
lint rules that require an enum or a discriminated union for a closed set

Before

```typescript
if (foo.status === "reddy") ship(foo);
```

After

```typescript
enum FooStatus { Ready, Shipped }
if (foo.status === FooStatus.Ready) ship(foo);
```

How it is checked

Checked by
lint rules that require an enum or a discriminated union for a closed set

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Stringly Typed Programming](https://banes-lab.com/records/architecture/stringly-typed-programming.md)

### Boolean Trap

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [architecture_evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which boolean parameters hide the intent of a call site.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Intent-Revealing Interface](https://banes-lab.com/records/architecture/intent-revealing-interface.md)

Violated by
Use boolean parameters or flags that hide intent and create ambiguous call sites or combinatorial behavior.

Detected by
method(true, false), multiple_boolean_params, flag_argument_controls_behavior

Measured by
calls that pass more than one boolean literal

Refactored by
replace_boolean_with_enum, split_method, introduce_options_object, name_intent

Enforced by
a lint rule against positional boolean parameters

Refused by rules
boolean-trap

Before

```typescript
createFoo(true, false, true);
```

After

```typescript
createFoo({ active: true, archived: false, notify: true });
```

How it is checked

Checked by
a lint rule against positional boolean parameters

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Boolean Trap](https://banes-lab.com/records/architecture/boolean-trap.md)

### Long Parameter List

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md), [object_creation](https://banes-lab.com/records/force/object-creation.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a signature grows so many parameters that a caller can no longer read or validate it.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Value Object](https://banes-lab.com/records/architecture/value-object.md)

Violated by
Grow function or constructor signatures until related inputs, optional modes, and dependencies become hard to understand or validate.

Detected by
arity_above_threshold, repeated_parameter_groups, many_optional_params

Measured by
parameters per signature above the threshold

Refactored by
introduce_parameter_object, builder, [value_object](https://banes-lab.com/records/architecture/value-object.md), dependency_container

Enforced by
a lint rule on parameter count

Before

```typescript
function makeFoo(a, b, c, d, e, f, g) {}
```

After

```typescript
interface MakeFooInput { a: A; b: B; c: C; d: D; e: E; f: F; g: G; }
function makeFoo(input: MakeFooInput) {}
```

How it is checked

Checked by
a lint rule on parameter count

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Long Parameter List](https://banes-lab.com/records/architecture/long-parameter-list.md)

### Magic Value

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [domain_boundary](https://banes-lab.com/records/force/domain-boundary.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which policy, thresholds or states are written as unexplained literals.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Single Source of Truth](https://banes-lab.com/records/architecture/single-source-of-truth.md)

Violated by
Encode policy, thresholds, status, timing, permissions, or domain rules as unexplained literals.

Detected by
repeated_number_literal, unexplained_string_literal, inline_threshold, hidden_timeout

Measured by
unnamed literals in conditions

Refactored by
name_constant, centralize_rule, externalize_config_if_runtime_variable, document_semantics

Enforced by
a lint rule against unnamed numeric and string literals in logic

Before

```typescript
if (foo.retries > 3) fail(foo);
```

After

```typescript
const MAX_FOO_RETRIES = 3;
if (foo.retries > MAX_FOO_RETRIES) fail(foo);
```

How it is checked

Checked by
a lint rule against unnamed numeric and string literals in logic

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Magic Value](https://banes-lab.com/records/architecture/magic-value.md)

### Speculative Generality

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [runtime_extensibility](https://banes-lab.com/records/force/runtime-extensibility.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which abstractions are built for variation that has no evidence of arriving.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Minimum Viable Architecture](https://banes-lab.com/records/architecture/minimum-viable-architecture.md)

Violated by
Build abstractions, extension points, layers, or configuration for variation that has no evidence of existing or near-term need.

Detected by
single_implementation_interface, unused_extension_point, config_never_varies, abstract_base_without_variants

Measured by
interfaces with one implementation, unused extension points

Refactored by
inline_abstraction, remove_unused_extension, defer_generalization, apply_minimum_viable_architecture

Enforced by
dead-code and single-implementation analysis, [design review](https://banes-lab.com/records/architecture/design-review.md)

Before

```typescript
abstract class AbstractFooProviderFactoryBase<T> { abstract create(): T; }
```

After

```typescript
function createFoo(input: CreateFooInput): Foo { return Foo.create(input); }
```

How it is checked

Checked by
dead-code and single-implementation analysis, design review

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Speculative Generality](https://banes-lab.com/records/architecture/speculative-generality.md)

### Premature Abstraction

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a shared abstraction is extracted before its variation is understood, so it fits no caller well.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Evolutionary Architecture](https://banes-lab.com/records/architecture/evolutionary-architecture.md)

Contracts
[Pattern Distiller Kernel](https://banes-lab.com/records/algorithms/pattern-distiller-kernel.md)

Distinct from
[Zombie Code](https://banes-lab.com/records/architecture/zombie-code.md): Premature abstraction extracts shared code too early, while zombie code leaves dead code in place.

Violated by
Extract a shared abstraction before variation is understood, causing the abstraction to fit no use case well.

Detected by
many_flags_in_shared_abstraction, subclasses_override_most_behavior, callers_work_around_abstraction

Measured by
flags and overrides per shared abstraction

Refactored by
duplicate_until_pattern_stabilizes, split_abstraction, extract_later_from_evidence

Enforced by
design review against evidence of recurrence

Before

```typescript
interface FooStrategy { run(): void; }
class OnlyFooStrategy implements FooStrategy { run() {} }
```

After

```typescript
function runFoo() {}
```

How it is checked

Checked by
design review against evidence of recurrence

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Premature Abstraction](https://banes-lab.com/records/architecture/premature-abstraction.md)

### Over-Abstraction

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which layers, interfaces and factories outnumber the variation they serve.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Minimum Viable Architecture](https://banes-lab.com/records/architecture/minimum-viable-architecture.md)

Distinct from
[Speculative Generality](https://banes-lab.com/records/architecture/speculative-generality.md): Over-abstraction is the state of having more layers than variation, while speculative generality is the cause, building for variation not yet seen.

Violated by
Add too many interfaces, layers, factories, adapters, or generic types relative to actual variability.

Detected by
deep_call_stack_for_simple_task, one_method_interfaces, factory_of_factory, abstraction_ratio_too_high

Measured by
indirection depth for simple operations, abstraction-to-implementation ratio

Refactored by
collapse_layers, inline_interface, remove_unused_indirection, preserve_only_real_boundaries

Enforced by
abstraction-ratio analysis, [design review](https://banes-lab.com/records/architecture/design-review.md)

Before

```typescript
const foo = fooFactoryProvider.getFactory().createBuilder().build();
```

After

```typescript
const foo = Foo.create(input);
```

How it is checked

Checked by
abstraction-ratio analysis, design review

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Over-Abstraction](https://banes-lab.com/records/architecture/over-abstraction.md)

### Golden Hammer

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [architecture_evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which one familiar solution is applied to problems regardless of fit.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[First-Principles Design](https://banes-lab.com/records/architecture/first-principles-design.md)

Violated by
Apply a familiar pattern, framework, architecture style, or technology to problems regardless of fit.

Detected by
same_pattern_everywhere, solution_precedes_problem, ADR_missing_alternatives, high_workaround_count

Measured by
decisions recorded without alternatives

Refactored by
force_analysis, tradeoff_matrix, ADR_with_alternatives, contextual_pattern_selection

Enforced by
decision records that require alternatives and the forces they answer

Before

```typescript
const config = parseFooConfig(runRegexOverEverything(rawYaml));
```

After

```typescript
const config = FooConfigSchema.parse(yaml.load(rawYaml));
```

How it is checked

Checked by
decision records that require alternatives and the forces they answer

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Golden Hammer](https://banes-lab.com/records/architecture/golden-hammer.md)

### Pattern Cargo Cult

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md)
- Aliases: Cargo-Cult Pattern Use
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a pattern's name and shape are copied without the forces, contracts and checks that make it work.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[First-Principles Design](https://banes-lab.com/records/architecture/first-principles-design.md)

Distinct from
[Golden Hammer](https://banes-lab.com/records/architecture/golden-hammer.md): A cargo cult copies a pattern's shape without its forces, while a golden hammer applies one familiar solution to every problem.

Violated by
Copy named patterns or architecture styles without implementing their required forces, contracts, constraints, or validation gates.

Detected by
ports_without_boundary_rules, plugins_without_contracts, events_without_idempotency, microservices_without_autonomy

Measured by
patterns missing their required boundary rules or contracts

Refactored by
validate_required_forces, add_missing_contracts, rename_if_not_pattern, remove_pattern_shell

Enforced by
architecture tests that check each named pattern's required contracts

Before

```typescript
class FooSingletonFactoryObserverProxy {}
```

After

```typescript
class FooService { constructor(private readonly store: FooStore) {} }
```

How it is checked

Checked by
architecture tests that check each named pattern's required contracts

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Pattern Cargo Cult](https://banes-lab.com/records/architecture/pattern-cargo-cult.md)

### Lava Flow

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [architecture_evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which obsolete or half-migrated code survives because nothing records whether it is still needed.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Evolutionary Architecture](https://banes-lab.com/records/architecture/evolutionary-architecture.md)

Distinct from
[Premature Abstraction](https://banes-lab.com/records/architecture/premature-abstraction.md): Lava flow is obsolete code kept too long, while premature abstraction is shared code extracted too early.

Distinct from
[Zombie Code](https://banes-lab.com/records/architecture/zombie-code.md): Lava flow is code that may still run and whose purpose nobody records, while zombie code is unreachable or disabled.

Violated by
Preserve obsolete, half-migrated, or unexplained code paths because no record says whether they are still needed.

Detected by
old_paths_never_called, deprecated_code_without_removal_date, feature_flags_stuck_on_or_off, comments_say_do_not_touch

Measured by
code paths with no runtime hits, deprecated code past its removal date

Refactored by
usage_instrumentation, owner_assignment, deprecation_plan, delete_after_evidence

Enforced by
dead-code analysis, removal dates on deprecated paths

Before

```typescript
function saveFoo(foo) {
legacySaveV1(foo);
if (false) legacySaveV2(foo);
newSave(foo);
}
```

After

```typescript
function saveFoo(foo: Foo) { return fooStore.save(foo); }
```

How it is checked

Checked by
dead-code analysis, removal dates on deprecated paths

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Lava Flow](https://banes-lab.com/records/architecture/lava-flow.md)

### Zombie Code

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [architecture_evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which unreachable or disabled code stays in the system and misleads the developer and the model.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Evolutionary Architecture](https://banes-lab.com/records/architecture/evolutionary-architecture.md)

Violated by
Leave unreachable, unused, or disabled code in the system where it keeps misleading the developer and the model, and can be reactivated by accident.

Detected by
unused_exports, unreachable_branches, dead_feature_flags, zero_runtime_hits

Measured by
unused exports, unreachable branches

Refactored by
delete_code, archive_reference, remove_exports, add_dead_code_check

Enforced by
unused-export and unreachable-code checks in the build

Before

```typescript
function computeFoo() {}
function computeFooOld() {}
function computeFooDeprecated() {}
```

After

```typescript
function computeFoo() {}
```

How it is checked

Checked by
unused-export and unreachable-code checks in the build

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Zombie Code](https://banes-lab.com/records/architecture/zombie-code.md)

### Temporal Coupling

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md), [causality_ordering](https://banes-lab.com/records/force/causality-ordering.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which operations must be called in an undocumented order to work.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Statelessness](https://banes-lab.com/records/architecture/statelessness.md)

Violated by
Require operations to be called in a specific undocumented order for correctness.

Detected by
must_call_initialize_first, method_fails_before_setup, order_dependent_tests, state_machine_hidden_in_calls

Measured by
operations that fail when called out of order

Refactored by
encode_state_machine, constructor_valid_state, make_order_explicit, add_precondition

Enforced by
types or constructors that only produce valid states, precondition checks

Before

```typescript
foo.init();
foo.configure();
foo.start();
```

After

```typescript
const foo = Foo.start(config);
```

How it is checked

Checked by
types or constructors that only produce valid states, precondition checks

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Temporal Coupling](https://banes-lab.com/records/architecture/temporal-coupling.md)

### Hidden Side Effect

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [event_messaging](https://banes-lab.com/records/force/event-messaging.md)
- Aliases: Hidden Side Effects
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which an operation that looks like a query mutates state or performs I/O that its name and signature do not show.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Principle of Least Surprise](https://banes-lab.com/records/architecture/principle-of-least-surprise.md), [Controlled Side Effects](https://banes-lab.com/records/architecture/controlled-side-effects.md)

Distinct from
[Action at a Distance](https://banes-lab.com/records/architecture/action-at-a-distance.md): A hidden side effect is a query that writes, while action at a distance is one part changing behavior elsewhere through globals or listeners.

Violated by
Make an operation appear like a query or pure function while it mutates state, performs I/O, emits events, or changes global context.

Detected by
getter_mutates_state, query_writes, function_emits_event_unexpectedly, global_context_modified

Measured by
queries that write or emit

Refactored by
rename_command, separate_query_from_command, make_effect_explicit, move_to_effect_boundary

Enforced by
command–query separation rules in lint, effect-boundary review

Before

```typescript
function getFoo(id: FooId) { audit.log(id); return fooStore.find(id); }
```

After

```typescript
function getFoo(id: FooId) { return fooStore.find(id); }
function auditFooAccess(id: FooId) { audit.log(id); }
```

How it is checked

Checked by
command–query separation rules in lint, effect-boundary review

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Hidden Side Effect](https://banes-lab.com/records/architecture/hidden-side-effect.md)

### Action at a Distance

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [event_messaging](https://banes-lab.com/records/force/event-messaging.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which one part of the system changes behavior elsewhere through globals, patches or implicit listeners.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Controlled Side Effects](https://banes-lab.com/records/architecture/controlled-side-effects.md)

Violated by
Let one part of the system change behavior far away through globals, monkey patches, shared registries, ambient context, or implicit event listeners.

Detected by
monkey_patch, global_registry_mutation, ambient_context_write, implicit_subscriber_side_effect

Measured by
global mutations and implicit listener registrations

Refactored by
explicit_dependency, localize_effect, trace_causation, restrict_global_mutation

Enforced by
lint rules against global mutation and monkey patching

Before

```typescript
globalThis.fooFlag = true;
function runFoo() { if (globalThis.fooFlag) go(); }
```

After

```typescript
function runFoo(options: { enabled: boolean }) { if (options.enabled) go(); }
```

How it is checked

Checked by
lint rules against global mutation and monkey patching

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Action at a Distance](https://banes-lab.com/records/architecture/action-at-a-distance.md)

### Ambient Context

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [state_transaction](https://banes-lab.com/records/force/state-transaction.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which request, tenant or user state is read from implicit global context.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Dependency Injection](https://banes-lab.com/records/architecture/dependency-injection.md)

Violated by
Read user, tenant, locale, transaction, permissions, or request state from implicit global context instead of explicit parameters or scoped context objects.

Detected by
global_current_user, thread_local_business_data, implicit_tenant_lookup, hidden_transaction_context

Measured by
global context reads outside infrastructure code

Refactored by
pass_context_explicitly, scope_context_object, inject_request_context, limit_ambient_use_to_infrastructure

Enforced by
lint rules against global context reads in business logic

Before

```typescript
function saveFoo(foo) { return CurrentTenant.get().db.save(foo); }
```

After

```typescript
function saveFoo(foo: Foo, tenant: Tenant) { return tenant.db.save(foo); }
```

How it is checked

Checked by
lint rules against global context reads in business logic

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Ambient Context](https://banes-lab.com/records/architecture/ambient-context.md)

### Inconsistent Error Model

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [model_governance](https://banes-lab.com/records/force/model-governance.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which one class of failure is reported through several incompatible shapes.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Semantic Consistency](https://banes-lab.com/records/architecture/semantic-consistency.md)

Violated by
Mix exceptions, nulls, booleans, strings, partial objects, console logging, and silent failure for the same error class.

Detected by
same_error_returns_null_or_throws, mixed_error_shapes, string_errors, partial_success_without_contract

Measured by
distinct error shapes per error class

Refactored by
typed_result, standard_error_contract, [error_boundary](https://banes-lab.com/records/algorithms/error-boundary.md), normalize_failure_modes

Enforced by
a typed error contract held by the type checker, lint rules against thrown strings

Before

```typescript
function a() { return null; }
function b() { throw "bad"; }
function c() { return { error: true }; }
```

After

```typescript
function a(): Result<Foo, FooError> {}
function b(): Result<Bar, FooError> {}
function c(): Result<Baz, FooError> {}
```

How it is checked

Checked by
a typed error contract held by the type checker, lint rules against thrown strings

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Inconsistent Error Model](https://banes-lab.com/records/architecture/inconsistent-error-model.md)

### Exception Control Flow

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which exceptions carry expected branching or normal absence.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Error Handling](https://banes-lab.com/records/architecture/error-handling.md)

Violated by
Use exceptions for expected branching, normal absence, validation alternatives, or loop control.

Detected by
try_catch_for_lookup_absence, exceptions_in_hot_loop, catch_chooses_normal_path

Measured by
catch blocks on expected-absence paths

Refactored by
return_result_type, use_option_type, validate_before_call, branch_explicitly

Enforced by
lint rules against catch blocks that choose the normal path

Before

```typescript
try {
return await fooStore.find(id);
} catch (notFound) {
return fooStore.create(id);
}
```

After

```typescript
const foo = await fooStore.find(id);
return foo ?? fooStore.create(id);
```

How it is checked

Checked by
lint rules against catch blocks that choose the normal path

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Exception Control Flow](https://banes-lab.com/records/architecture/exception-control-flow.md)

### Null Semantics Drift

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [semantic_consistency](https://banes-lab.com/records/force/semantic-consistency.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which null, empty, zero and missing are used interchangeably for one field.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Null Object Pattern](https://banes-lab.com/records/architecture/null-object-pattern.md)

Violated by
Use null, undefined, empty string, zero, false, missing field, and empty collection interchangeably.

Detected by
null_and_empty_string_same_field, optional_field_without_semantics, truthy_checks_for_domain_state

Measured by
fields with more than one representation of absence

Refactored by
define_absence_semantics, use_option_result, schema_nullability, normalize_input

Enforced by
schema nullability rules, strict null checking

Before

```typescript
const foo = find(id);
if (foo) use(foo);
```

After

```typescript
const foo = find(id) ?? Foo.none();
foo.use();
```

How it is checked

Checked by
schema nullability rules, strict null checking

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Null Semantics Drift](https://banes-lab.com/records/architecture/null-semantics-drift.md)

### Anemic Domain Model

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [semantic_consistency](https://banes-lab.com/records/force/semantic-consistency.md), [model_governance](https://banes-lab.com/records/force/model-governance.md), [domain_boundary](https://banes-lab.com/records/force/domain-boundary.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which domain objects hold data only, while their rules live in services and handlers.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Aggregate](https://banes-lab.com/records/architecture/aggregate.md), [Entity](https://banes-lab.com/records/architecture/entity.md)

Violated by
Store domain data in passive objects while business rules live in services, controllers, handlers, or scripts.

Detected by
entities_with_getters_setters_only, services_contain_all_rules, validation_outside_aggregate

Measured by
domain types without behavior, rules outside their aggregate

Refactored by
move_behavior_to_domain, add_value_object, add_aggregate_invariant, encapsulate_state

Enforced by
architecture tests that locate domain rules, [design review](https://banes-lab.com/records/architecture/design-review.md)

Before

```typescript
class Foo { status: string; }
function shipFoo(foo: Foo) { if (foo.status === "ready") foo.status = "shipped"; }
```

After

```typescript
class Foo {
private status = FooStatus.Ready;
ship() { if (this.status !== FooStatus.Ready) throw new NotReadyError(); this.status = FooStatus.Shipped; }
}
```

How it is checked

Checked by
architecture tests that locate domain rules, design review

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Anemic Domain Model](https://banes-lab.com/records/architecture/anemic-domain-model.md)

### Transaction Script Sprawl

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [state_transaction](https://banes-lab.com/records/force/state-transaction.md), [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md), [domain_boundary](https://banes-lab.com/records/force/domain-boundary.md), [control_coordination](https://banes-lab.com/records/force/control-coordination.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which business processes are procedural scripts that coordinate validation, persistence and decisions directly.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Domain Service](https://banes-lab.com/records/architecture/domain-service.md)

Violated by
Encode business processes as procedural scripts that directly coordinate validation, persistence, external calls, and domain decisions.

Detected by
large_service_method, business_rules_in_controller, repeated_procedure_blocks

Measured by
procedure length, business rules in handlers

Refactored by
extract_domain_model, extract_use_case, separate_ports, move_rules_to_domain

Enforced by
architecture tests on layer responsibilities, method size limits

Before

```typescript
function createFooHandler(req) {
validate(req); price(req); tax(req); persist(req); notify(req);
}
```

After

```typescript
class CreateFoo {
constructor(private readonly foos: FooRepository) {}
execute(input: CreateFooInput) { const foo = Foo.create(input); return this.foos.save(foo); }
}
```

How it is checked

Checked by
architecture tests on layer responsibilities, method size limits

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Transaction Script Sprawl](https://banes-lab.com/records/architecture/transaction-script-sprawl.md)

### Fat Controller

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md), [security_governance](https://banes-lab.com/records/force/security-governance.md), [control_coordination](https://banes-lab.com/records/force/control-coordination.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which controllers hold validation, business rules, persistence and response formatting.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Domain Service](https://banes-lab.com/records/architecture/domain-service.md)

Distinct from
[Transaction Script Sprawl](https://banes-lab.com/records/architecture/transaction-script-sprawl.md): A fat controller puts business logic in the request handler, while transaction script sprawl writes business processes as procedural scripts wherever they live.

Violated by
Put validation, business rules, persistence orchestration, mapping, authorization, and response formatting in the controller layer.

Detected by
controller_method_too_large, repository_calls_plus_business_rules, domain_logic_in_route_handler

Measured by
controller method size, repository calls from controllers

Refactored by
extract_use_case, move_domain_logic, add_request_mapper, add_application_service

Enforced by
layer rules that keep domain logic out of controllers, size limits

Before

```typescript
class FooController {
create(req) { const foo = { ...req.body }; if (!foo.name) throw 0; db.insert(foo); email(foo); }
}
```

After

```typescript
class FooController {
constructor(private readonly createFoo: CreateFoo) {}
create(req: Request) { return this.createFoo.execute(req.body); }
}
```

How it is checked

Checked by
layer rules that keep domain logic out of controllers, size limits

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Fat Controller](https://banes-lab.com/records/architecture/fat-controller.md)

### Repository Dump

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md), [domain_boundary](https://banes-lab.com/records/force/domain-boundary.md), [control_coordination](https://banes-lab.com/records/force/control-coordination.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a repository accumulates business queries, policy and orchestration until it is a second service layer.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Interface Segregation Principle (ISP)](https://banes-lab.com/records/architecture/interface-segregation.md)

Violated by
Place business-specific querying, orchestration, mapping, caching, validation, and policy into a repository until it becomes a second service layer.

Detected by
repository_methods_encode_business_process, authorization_in_repository, repository_calls_external_services

Measured by
business-specific methods per repository

Refactored by
extract_query_service, move_policy_to_domain_or_use_case, split_repository, define_persistence_contract

Enforced by
persistence-boundary rules, [design review](https://banes-lab.com/records/architecture/design-review.md)

Before

```typescript
class FooRepository { findActiveFoosForBarInRegionSortedByBaz() {} }
```

After

```typescript
class FooRepository { find(spec: FooSpecification): Foo[] { return this.query(spec.toQuery()); } }
```

How it is checked

Checked by
persistence-boundary rules, design review

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Repository Dump](https://banes-lab.com/records/architecture/repository-dump.md)

### Utility Dump

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [domain_boundary](https://banes-lab.com/records/force/domain-boundary.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which unrelated helpers accumulate in a generic utility module that no one owns.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[High Cohesion](https://banes-lab.com/records/architecture/high-cohesion.md)

Distinct from
[Shotgun Surgery](https://banes-lab.com/records/architecture/shotgun-surgery.md): A utility dump gathers unrelated helpers in one module, while shotgun surgery spreads one responsibility across many files.

Violated by
Accumulate unrelated helper functions in generic utility modules without ownership, cohesion, or domain language.

Detected by
utils_file_growth, unrelated_helpers, many_modules_import_same_dump, generic_names

Measured by
unrelated functions per utility module, importers per utility module

Refactored by
move_helper_to_owner, split_by_domain, extract_value_object, name_concept

Enforced by
naming rules that reject catch-all module names, cohesion analysis

Before

```typescript
export function formatFoo() {}
export function parseBar() {}
export function hashBaz() {}
```

After

```typescript
export const fooFormatter = { format(foo: Foo): string {} };
export const barParser = { parse(raw: string): Bar {} };
```

How it is checked

Checked by
naming rules that reject catch-all module names, cohesion analysis

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Utility Dump](https://banes-lab.com/records/architecture/utility-dump.md)

### Framework Leakage

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [domain_boundary](https://banes-lab.com/records/force/domain-boundary.md)
- Aliases: Infrastructure-Centric Design
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which framework or infrastructure types, annotations or lifecycles enter core domain logic, so business rules depend on technical specifics.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Ports and Adapters Architecture](https://banes-lab.com/records/architecture/ports-and-adapters-architecture.md)

Violated by
Let framework classes, decorators, lifecycle assumptions, request objects, ORM entities, or infrastructure annotations enter core domain logic.

Detected by
request_object_in_domain, ORM_entity_as_domain, framework_annotation_in_core, container_lookup_in_business_logic

Measured by
framework imports in core modules

Refactored by
add_adapter, map_to_domain_model, introduce_port, move_framework_outward

Enforced by
import rules that keep framework packages out of the core

Before

```typescript
class Foo { @Column() name: string; @OneToMany() bars: Bar[]; }
```

After

```typescript
class Foo { constructor(readonly name: string, readonly bars: readonly Bar[]) {} }
class FooEntity { @Column() name: string; }
```

How it is checked

Checked by
import rules that keep framework packages out of the core

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Framework Leakage](https://banes-lab.com/records/architecture/framework-leakage.md)

### Vendor Lock-In Leakage

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [model_governance](https://banes-lab.com/records/force/model-governance.md), [domain_boundary](https://banes-lab.com/records/force/domain-boundary.md)
- Aliases: Shared Model Coupling
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which an external system's or a vendor's APIs, errors and models spread through application and domain code, so their changes ripple across it.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Anti-Corruption Layer](https://banes-lab.com/records/architecture/anti-corruption-layer.md)

Violated by
Spread vendor-specific APIs, models, exceptions, identifiers, or configuration throughout application and domain code.

Detected by
vendor_imports_outside_adapter, vendor_error_types_in_domain, vendor_schema_as_canonical_model

Measured by
vendor imports outside adapters

Refactored by
extract_vendor_adapter, define_port, translate_errors, own_canonical_model

Enforced by
import rules that confine vendor packages to adapters

Before

```typescript
import { BlobStore } from "acme-blob-sdk";
function saveFoo(foo) { return new BlobStore().putObject(foo); }
```

After

```typescript
interface FooBlobStore { put(foo: Foo): Promise<void>; }
function saveFoo(foo: Foo, store: FooBlobStore) { return store.put(foo); }
```

How it is checked

Checked by
import rules that confine vendor packages to adapters

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Vendor Lock-In Leakage](https://banes-lab.com/records/architecture/vendor-lock-in-leakage.md)

### Circular Dependency

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md)
- Aliases: Cyclic Dependencies
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which modules depend on each other, directly or through others, so none can change alone.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Directed Acyclic Graph (DAG)](https://banes-lab.com/records/architecture/directed-acyclic-graph.md), [Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md)

Distinct from
[Inappropriate Intimacy](https://banes-lab.com/records/architecture/inappropriate-intimacy.md): A circular dependency is a cycle in the dependency graph, while inappropriate intimacy is a dependency on another module's internals, with or without a cycle.

Distinct from
[Message Chain](https://banes-lab.com/records/architecture/message-chain.md): A circular dependency is a cycle between modules, while a message chain is a client walking a chain of objects.

Violated by
Allow modules to depend on each other directly or indirectly until no module can change, test, deploy, or initialize independently.

Detected by
dependency_cycle, mutual_imports, bootstrap_order_hacks, bidirectional_service_calls

Measured by
dependency cycles and their length

Refactored by
invert_dependency, extract_interface, split_shared_contract, introduce_event_or_mediator

Enforced by
a dependency-cycle check in the build

Refused by rules
circular-dependency

Before

```typescript
import { bar } from "./bar";
export const foo = () => bar();
import { foo } from "./foo";
export const bar = () => foo();
```

After

```typescript
export const foo = (run: () => void) => run();
export const bar = () => {};
foo(bar);
```

How it is checked

Checked by
a dependency-cycle check in the build

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Circular Dependency](https://banes-lab.com/records/architecture/circular-dependency.md)

### Cyclic Deployment Dependency

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [architecture_evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which services must deploy in lockstep because each depends on the other's current version.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Autonomy](https://banes-lab.com/records/architecture/autonomy.md)

Violated by
Require two or more services or packages to deploy in lockstep because each depends on the other’s current behavior.

Detected by
coordinated_release_required, consumer_breaks_without_provider_release, mutual_contract_change

Measured by
releases that required coordinated deployment

Refactored by
version_contract, backward_compatible_change, consumer_driven_contract_tests, adapter_phase_migration

Enforced by
consumer-driven contract tests, independent-deployment checks

Before

```typescript
fooService.callsAtStartup(barService);
barService.callsAtStartup(fooService);
```

After

```typescript
fooService.publishes(fooReady);
barService.subscribes(fooReady);
```

How it is checked

Checked by
consumer-driven contract tests, independent-deployment checks

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Cyclic Deployment Dependency](https://banes-lab.com/records/architecture/cyclic-deployment-dependency.md)

### Synchronous Chain Trap

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md)
- Aliases: Blocking Synchronous Chains
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which one request depends on a deep chain of blocking synchronous remote calls, so one slow link stalls the whole request.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Asynchronous Communication](https://banes-lab.com/records/architecture/asynchronous-communication.md)

Violated by
Build deep request-time chains across services or modules, making latency, availability, and failure behavior multiplicative.

Detected by
sync_depth_above_threshold, request_path_many_remote_calls, cascading_timeout

Measured by
synchronous call depth per request path

Refactored by
collapse_reads, introduce_async_event, cache_read_model, apply_timeout_bulkhead

Enforced by
call-depth limits in architecture review, timeout and bulkhead policies

Before

```typescript
const foo = await a();
const bar = await b(foo);
const baz = await c(bar);
return slowSyncCall(a, b, c);
```

After

```typescript
const [foo, bar, baz] = await Promise.all([a(), b(), c()]);
```

How it is checked

Checked by
call-depth limits in architecture review, timeout and bulkhead policies

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Synchronous Chain Trap](https://banes-lab.com/records/architecture/synchronous-chain-trap.md)

### Chatty Interface

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which one operation needs many small remote calls.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Uniform Interface](https://banes-lab.com/records/architecture/uniform-interface.md)

Violated by
Require many small remote calls to complete one user or business operation.

Detected by
N_plus_1_API_calls, many_calls_per_screen, loop_contains_remote_call

Measured by
remote calls per user operation

Refactored by
coarse_grained_endpoint, batch_api, query_projection, data_loader

Enforced by
API review, performance tests that bound call counts

Before

```typescript
const results = [];
for (const id of fooIds) results.push(await fooApi.get(id));
```

After

```typescript
const results = await fooApi.getMany(fooIds);
```

How it is checked

Checked by
API review, performance tests that bound call counts

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Chatty Interface](https://banes-lab.com/records/architecture/chatty-interface.md)

### N Plus One Query

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [architecture_evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a collection is fetched and then one further query is issued per item.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Algorithmic Efficiency](https://banes-lab.com/records/architecture/algorithmic-efficiency.md)

Violated by
Fetch a collection, then issue one query or remote call per item rather than fetching required related data intentionally.

Detected by
query_inside_loop, remote_call_inside_loop, query_count_scales_with_rows

Measured by
queries per request as the row count grows

Refactored by
batch_fetch, join_or_include, preload, cache_projection

Enforced by
query-count assertions in integration tests

Before

```typescript
const foos = await fooStore.all();
for (const foo of foos) foo.bar = await barStore.find(foo.barId);
```

After

```typescript
const foos = await fooStore.all();
const bars = await barStore.findMany(foos.map(f => f.barId));
```

How it is checked

Checked by
query-count assertions in integration tests

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[N Plus One Query](https://banes-lab.com/records/architecture/n-plus-one-query.md)

### Cache Poisoning by Design

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md), [security_governance](https://banes-lab.com/records/force/security-governance.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a cache key omits an input the entry depends on, so one request is served another's result.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Caching](https://banes-lab.com/records/architecture/caching.md)

Violated by
Cache data without key correctness, tenant isolation, authorization context, invalidation, or schema version, or key the entry by time or lifetime alone.

Detected by
cache_key_missing_user_or_tenant, cache_without_version, cache_keyed_by_time, no_invalidation, authorization_not_in_cache_key

Measured by
cache keys missing tenant, identity or version

Refactored by
define_cache_contract, include_context_in_key, key_by_input_fingerprint, add_invalidation, add_schema_version

Enforced by
cache-key review, tests that vary tenant and version

Before

```typescript
fooCache.set(request.path, response);
```

After

```typescript
if (response.ok && response.cacheable) {
fooCache.set(cacheKey(request.identity, request.path, fingerprint(request.inputs, SCHEMA_VERSION)), response);
}
```

How it is checked

Checked by
cache-key review, tests that vary tenant and version

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Cache Poisoning by Design](https://banes-lab.com/records/architecture/cache-poisoning-by-design.md)

### Retry Storm

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [resilience_recovery](https://banes-lab.com/records/force/resilience-recovery.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which clients retry a failing dependency so aggressively that the retries prolong the failure.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Circuit Breaker Pattern](https://banes-lab.com/records/architecture/circuit-breaker-pattern.md)

Violated by
Allow many clients or workers to retry failed dependencies aggressively and synchronously, increasing pressure on the failing system.

Detected by
no_backoff, no_jitter, unbounded_retries, retry_on_non_idempotent_operation

Measured by
retries per failed call, retry share of load during incidents

Refactored by
bounded_retry, exponential_backoff, jitter, circuit_breaker, idempotency_key

Enforced by
a resilience policy that requires bounded retries with backoff and jitter

Before

```typescript
while (true) { try { return await call(); } catch { } }
```

After

```typescript
return retry(call, { attempts: 5, backoff: exponentialJitter(), giveUp: dlq });
```

How it is checked

Checked by
a resilience policy that requires bounded retries with backoff and jitter

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Retry Storm](https://banes-lab.com/records/architecture/retry-storm.md)

### Timeout Omission

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [resilience_recovery](https://banes-lab.com/records/force/resilience-recovery.md)
- Aliases: Infinite Wait
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which calls to external systems carry no timeout, cancellation or deadline, so a caller can wait for ever on work that never completes.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Timeout Pattern](https://banes-lab.com/records/architecture/timeout-pattern.md)

Violated by
Call external systems without explicit timeouts, cancellation, or deadline propagation.

Detected by
HTTP_call_without_timeout, DB_query_without_timeout, missing_cancellation_token, no_deadline_propagation

Measured by
outbound calls without a timeout

Refactored by
add_timeout, propagate_deadline, add_cancellation, fallback_or_failfast

Enforced by
a lint rule that requires a timeout on outbound calls

Before

```typescript
const foo = await fetch(fooUrl);
```

After

```typescript
const foo = await fetch(fooUrl, { signal: AbortSignal.timeout(5000) });
```

How it is checked

Checked by
a lint rule that requires a timeout on outbound calls

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Timeout Omission](https://banes-lab.com/records/architecture/timeout-omission.md)

### Missing Backpressure

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [resilience_recovery](https://banes-lab.com/records/force/resilience-recovery.md)
- Aliases: Unbounded Ingestion
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a system accepts work faster than it can process it, with no limit or shedding.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Backpressure](https://banes-lab.com/records/architecture/backpressure.md)

Violated by
Accept work faster than the system can process it without queue limits, admission control, rate limits, or shedding.

Detected by
unbounded_queue, no_rate_limit, no_admission_control, memory_grows_with_load

Measured by
queue depth and memory growth under load

Refactored by
bounded_queue, rate_limit, load_shed, apply_backpressure_signal

Enforced by
load tests, checks that every queue is configured with a bound

Before

```typescript
stream.on("data", d => queue.push(process(d)));
```

After

```typescript
stream.pipe(new BoundedFooProcessor({ highWaterMark: 100 }));
```

How it is checked

Checked by
load tests, checks that every queue is configured with a bound

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Missing Backpressure](https://banes-lab.com/records/architecture/missing-backpressure.md)

### Silent Data Corruption

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which invalid data is accepted, transformed or stored without any check noticing.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Fail Fast](https://banes-lab.com/records/architecture/fail-fast.md)

Violated by
Accept, transform, or persist invalid data without validation, checksums, invariants, reconciliation, or audit.

Detected by
missing_boundary_validation, no_invariant_check, impossible_state_in_database, reconciliation_failures

Measured by
invariant violations and reconciliation mismatches

Refactored by
validate_at_boundary, add_invariants, add_reconciliation, audit_data_changes

Enforced by
boundary validation, invariant checks, reconciliation jobs

Before

```typescript
const total = Number(a) + Number(b);
save(total);
```

After

```typescript
const total = Money.add(Money.parse(a), Money.parse(b));
save(total);
```

How it is checked

Checked by
boundary validation, invariant checks, reconciliation jobs

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Silent Data Corruption](https://banes-lab.com/records/architecture/silent-data-corruption.md)

### Lost Update

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [state_transaction](https://banes-lab.com/records/force/state-transaction.md)
- Aliases: Whole-File Write Race
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which concurrent writers overwrite each other's changes without a version check.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Write Barrier](https://banes-lab.com/records/architecture/write-barrier.md), [Concurrency Control](https://banes-lab.com/records/architecture/concurrency-control.md)

Violated by
Allow concurrent writers to overwrite each other without version checks, locks, compare-and-swap, or transaction isolation.

Detected by
last_write_wins_without_version, no_optimistic_lock, concurrent_update_defects

Measured by
concurrent update conflicts found in tests

Refactored by
[optimistic_locking](https://banes-lab.com/records/architecture/optimistic-locking.md), [pessimistic_locking](https://banes-lab.com/records/architecture/pessimistic-locking.md), merge_policy, transaction_isolation

Enforced by
optimistic-locking checks, concurrency tests

Before

```typescript
const foo = await load(id);
foo.count += 1;
await save(foo);
```

After

```typescript
await fooStore.update(id, { count: increment(1) }, { expectedVersion: foo.version });
```

How it is checked

Checked by
optimistic-locking checks, concurrency tests

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Lost Update](https://banes-lab.com/records/architecture/lost-update.md)

### Dual Write

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [event_messaging](https://banes-lab.com/records/force/event-messaging.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which related state is written to two systems with no atomicity or compensation.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Outbox Pattern](https://banes-lab.com/records/architecture/outbox-pattern.md)

Violated by
Write related state to two systems without atomicity, outbox, saga, reconciliation, or compensation.

Detected by
database_write_then_message_publish, two_databases_updated_without_transaction_or_outbox, manual_repair_needed

Measured by
writes to two systems outside one transaction or outbox

Refactored by
transactional_outbox, [saga](https://banes-lab.com/records/lexicon/saga.md), [idempotent_consumer](https://banes-lab.com/records/architecture/idempotent-consumer.md), reconciliation_job

Enforced by
an outbox or saga, verified by integration tests

Before

```typescript
await db.save(foo);
await searchIndex.add(foo);
```

After

```typescript
await db.save(foo);
await outbox.append(fooCreatedEvent(foo));
```

How it is checked

Checked by
an outbox or saga, verified by integration tests

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Dual Write](https://banes-lab.com/records/architecture/dual-write.md)

### Read-Your-Writes Violation

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a writer reads back a stale copy of what it has just written.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Causal Consistency](https://banes-lab.com/records/architecture/causal-consistency.md)

Violated by
Let users or processes perform a write and then read from a stale replica, cache, projection, or eventually consistent view without explicit consistency contract.

Detected by
write_then_stale_read_defect, cache_not_invalidated_after_write, replica_read_after_write

Measured by
stale reads observed after writes

Refactored by
read_from_primary_after_write, invalidate_cache, show_pending_state, define_consistency_contract

Enforced by
consistency-contract tests that read after a write

Before

```typescript
await primaryDb.write(foo);
const view = await replicaDb.read(foo.id);
```

After

```typescript
await primaryDb.write(foo);
const view = await readAfterWrite(foo.id, { consistency: "read-your-writes" });
```

How it is checked

Checked by
consistency-contract tests that read after a write

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Read-Your-Writes Violation](https://banes-lab.com/records/architecture/read-your-writes-violation.md)

### Security Theater

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [security_governance](https://banes-lab.com/records/force/security-governance.md), [model_governance](https://banes-lab.com/records/force/model-governance.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which visible security controls leave the real threat unreduced, or can be bypassed.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Threat Modeling](https://banes-lab.com/records/architecture/threat-modeling.md)

Violated by
Add visible security controls that do not reduce the actual threat model or can be bypassed by alternate paths.

Detected by
control_not_linked_to_threat, bypass_endpoint, client_only_security, audit_passes_but_attack_succeeds

Measured by
controls not linked to a threat, bypass paths found

Refactored by
threat_model, server_side_enforcement, penetration_test, [policy_as_code](https://banes-lab.com/records/architecture/policy-as-code.md)

Enforced by
threat-model review, penetration tests

Before

```typescript
if (password.length > 0) grantFooAccess(user);
```

After

```typescript
const verified = await verifyPassword(password, user.passwordHash);
if (!verified) throw new UnauthorizedError();
grantFooAccess(user);
```

How it is checked

Checked by
threat-model review, penetration tests

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Security Theater](https://banes-lab.com/records/architecture/security-theater.md)

### Authorization Scattering

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [security_governance](https://banes-lab.com/records/force/security-governance.md), [model_governance](https://banes-lab.com/records/force/model-governance.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which authorization checks are spread across layers with no central policy.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Authorization](https://banes-lab.com/records/architecture/authorization.md)

Violated by
Spread authorization checks across controllers, services, repositories, UI, and ad hoc conditionals without a central policy model.

Detected by
repeated_role_checks, missing_policy_engine, endpoint_without_authz, inconsistent_resource_access

Measured by
endpoints without a policy check, duplicated role checks

Refactored by
centralize_policy, [policy_as_code](https://banes-lab.com/records/architecture/policy-as-code.md), ABAC_or_RBAC_model, authorization_tests

Enforced by
a policy engine, with authorization tests per endpoint

Before

```typescript
if (user.role === "admin") deleteFoo();
if (user.role === "admin" || user.id === foo.owner) editFoo();
```

After

```typescript
if (policy.can(user, "delete", foo)) deleteFoo();
if (policy.can(user, "edit", foo)) editFoo();
```

How it is checked

Checked by
a policy engine, with authorization tests per endpoint

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Authorization Scattering](https://banes-lab.com/records/architecture/authorization-scattering.md)

### Secret Sprawl

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [modularity](https://banes-lab.com/records/force/modularity.md), [security_governance](https://banes-lab.com/records/force/security-governance.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which credentials and keys are stored across code, logs and configuration.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Secrets Management](https://banes-lab.com/records/architecture/secrets-management.md)

Violated by
Store credentials, tokens, keys, certificates, or sensitive configuration across code, config files, logs, tickets, and local environments.

Detected by
secret_in_repo, secret_in_log, shared_static_token, manual_secret_distribution

Measured by
secrets found in source and logs

Refactored by
secret_manager, rotate_secret, scan_repository, least_privilege_credential

Enforced by
secret scanning in the build, a secret store

Before

```typescript
const key = "sk_live_abc123";
const dbPass = "hunter2";
```

After

```typescript
const key = await secrets.get("foo.api.key");
const dbPass = await secrets.get("foo.db.password");
```

How it is checked

Checked by
secret scanning in the build, a secret store

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Secret Sprawl](https://banes-lab.com/records/architecture/secret-sprawl.md)

### Personal Data Oversharing

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [architecture_evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- Aliases: Unbounded Data Collection
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which more personal data is collected, kept, logged or exposed than the declared purpose needs.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Privacy by Design](https://banes-lab.com/records/architecture/privacy-by-design.md)

Violated by
Collect, store, log, transmit, or expose more personal data than needed for the declared purpose.

Detected by
personal_data_in_logs, unused_sensitive_fields, broad_export, missing_data_minimization

Measured by
personal-data fields in logs and exports

Refactored by
[data_minimization](https://banes-lab.com/records/lexicon/data-minimization.md), field_redaction, purpose_binding, retention_policy

Enforced by
privacy review, log redaction rules

Before

```typescript
logger.info("created foo", { email: user.email, ssn: user.ssn });
```

After

```typescript
logger.info("created foo", { userId: user.id });
```

How it is checked

Checked by
privacy review, log redaction rules

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Personal Data Oversharing](https://banes-lab.com/records/architecture/personal-data-oversharing.md)

### Observability Noise

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [observability_traceability](https://banes-lab.com/records/force/observability-traceability.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which logs, metrics and alerts are too many and too low in signal to act on.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Alerting](https://banes-lab.com/records/architecture/alerting.md)

Violated by
Emit excessive, low-signal logs, metrics, traces, or alerts without severity, ownership, cardinality control, or actionability.

Detected by
high_alert_ack_without_action, high_cardinality_metrics, logs_without_context, duplicate_alerts

Measured by
alerts acknowledged without action, high-cardinality metrics

Refactored by
define_signal_quality, reduce_cardinality, add_runbook_owner, sample_or_aggregate

Enforced by
alert-ownership rules, metric cardinality limits

Before

```typescript
logger.info("entering loop");
for (const f of foos) logger.info("iter", f);
```

After

```typescript
logger.info("foo.batch.processed", { count: foos.length, durationMs });
```

How it is checked

Checked by
alert-ownership rules, metric cardinality limits

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Observability Noise](https://banes-lab.com/records/architecture/observability-noise.md)

### Log-as-Control-Flow

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md), [resilience_recovery](https://banes-lab.com/records/force/resilience-recovery.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a failure is logged as though logging handled it, and execution continues.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Logging](https://banes-lab.com/records/architecture/logging.md)

Violated by
Log errors or warnings as if logging itself handles the failure, while the system continues without recovery, propagation, or safe fallback.

Detected by
catch_log_continue, logged_error_without_return_or_throw, critical_log_no_alert

Measured by
catch blocks that log and continue

Refactored by
return_typed_error, fail_fast_or_fallback, add_recovery_policy, alert_critical_failure

Enforced by
a lint rule against catch blocks that only log

Before

```typescript
try { await chargeFoo(foo); } catch (error) { logger.error("foo.charge.failed", error); }
shipFoo(foo);
```

After

```typescript
const outcome = await chargeFoo(foo);
if (!outcome.ok) throw new ChargeFailedError(foo.id, outcome.error);
shipFoo(foo);
```

How it is checked

Checked by
a lint rule against catch blocks that only log

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Log-as-Control-Flow](https://banes-lab.com/records/architecture/log-as-control-flow.md)

### Manual Runbook Dependency

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [resilience_recovery](https://banes-lab.com/records/force/resilience-recovery.md)
- Aliases: Manual-Only Recovery, Manual Intervention Dependency
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which repeatable operational steps, such as detecting a failure and recovering from it, are performed by hand during incidents and deploys, so recovery waits on a person.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Self-Healing Architecture](https://banes-lab.com/records/architecture/self-healing-architecture.md), [Auto-Remediation](https://banes-lab.com/records/architecture/auto-remediation.md)

Violated by
Perform by hand the repeatable operational actions during incidents, deploys, migrations, or recovery.

Detected by
same_manual_incident_steps, manual_migration_sequence, operator_specific_knowledge

Measured by
manual steps repeated across incidents

Refactored by
automate_runbook, add_guardrails, validate_preconditions, record_execution_log

Enforced by
operations review of manual steps repeated across incidents

Before

```typescript
const RUNBOOK = "on failure, ssh in and run restart-foo.sh";
```

After

```typescript
health.onUnhealthy(() => orchestrator.restart("foo"));
```

How it is checked

Checked by
operations review of manual steps repeated across incidents

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Manual Runbook Dependency](https://banes-lab.com/records/architecture/manual-runbook-dependency.md)

### Big-Bang Release

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [state_transaction](https://banes-lab.com/records/force/state-transaction.md)
- Aliases: Big-Bang Deployment
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a large, irreversible change reaches every user at once, with no staged rollout.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Canary Deployment](https://banes-lab.com/records/architecture/canary-deployment.md)

Violated by
Ship a large, irreversible, all-user change without staged rollout, feature flags, canary, rollback, or blast-radius control.

Detected by
no_canary, no_feature_flag, no_rollback_plan, large_release_batch

Measured by
release batch size, releases without a rollback path

Refactored by
feature_flag, canary_deploy, blue_green, rollback_plan, small_batch_release

Enforced by
release gates that require a canary or a feature flag and a rollback plan

Before

```typescript
deployEverything("foo", "bar", "baz");
```

After

```typescript
release("foo", { strategy: canary(0.1) });
```

How it is checked

Checked by
release gates that require a canary or a feature flag and a rollback plan

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Big-Bang Release](https://banes-lab.com/records/architecture/big-bang-release.md)

### Irreversible Migration

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [architecture_evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a schema or data change can neither run beside the old version nor be rolled back.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Rollback](https://banes-lab.com/records/architecture/rollback.md)

Violated by
Apply schema, data, or infrastructure changes that cannot safely run alongside old versions or be rolled back.

Detected by
drop_column_before_consumers_removed, destructive_data_transform_no_backup, no_backward_compatible_phase

Measured by
migrations without a down step or a compatible phase

Refactored by
expand_contract_migration, backup, dual_read_write_temporarily, rollback_test

Enforced by
migration review, rollback tests

Before

```typescript
await db.exec("ALTER TABLE foo DROP COLUMN legacy_name");
```

After

```typescript
await migrate({ up: addFooName, down: restoreFooName });
```

How it is checked

Checked by
migration review, rollback tests

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Irreversible Migration](https://banes-lab.com/records/architecture/irreversible-migration.md)

### Big-Upfront Frozen Architecture

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [domain_boundary](https://banes-lab.com/records/force/domain-boundary.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which major architectural decisions are fixed before the forces they answer are known.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Evolutionary Architecture](https://banes-lab.com/records/architecture/evolutionary-architecture.md)

Distinct from
[Lava Flow](https://banes-lab.com/records/architecture/lava-flow.md): Frozen architecture fixes decisions too early, while lava flow keeps obsolete code too long.

Distinct from
[Premature Abstraction](https://banes-lab.com/records/architecture/premature-abstraction.md): Frozen architecture fixes system-level decisions early, while premature abstraction extracts one shared abstraction early.

Distinct from
[Zombie Code](https://banes-lab.com/records/architecture/zombie-code.md): Frozen architecture is a decision made too early, while zombie code is dead code left behind.

Violated by
Lock in major architectural decisions before validating domain forces, quality attributes, operational realities, and change vectors.

Detected by
heavy_architecture_before_usage, ADR_without_evidence, future-proofing_without_feedback

Measured by
decisions recorded without evidence

Refactored by
[minimum_viable_architecture](https://banes-lab.com/records/architecture/minimum-viable-architecture.md), [evolutionary_architecture](https://banes-lab.com/records/architecture/evolutionary-architecture.md), [fitness_functions](https://banes-lab.com/records/architecture/fitness-functions.md), decision_review

Enforced by
decision records that require evidence, periodic decision review

Before

```typescript
const ARCHITECTURE = designAllModulesForNextFiveYears();
```

After

```typescript
const foo = defineModule("foo", { exports: { createFoo } });
registry.add(foo);
```

How it is checked

Checked by
decision records that require evidence, periodic decision review

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Big-Upfront Frozen Architecture](https://banes-lab.com/records/architecture/big-upfront-frozen-architecture.md)

### Architecture Astronaut

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [model_governance](https://banes-lab.com/records/force/model-governance.md), [domain_boundary](https://banes-lab.com/records/force/domain-boundary.md)
- Aliases: Over-Architecture
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which abstract frameworks, meta-models and architectural structure are built ahead of the concrete needs they should serve.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Minimum Viable Architecture](https://banes-lab.com/records/architecture/minimum-viable-architecture.md)

Distinct from
[Over-Abstraction](https://banes-lab.com/records/architecture/over-abstraction.md): An astronaut builds frameworks for needs that have not arrived, while over-abstraction adds layers beyond the variation that exists.

Distinct from
[Speculative Generality](https://banes-lab.com/records/architecture/speculative-generality.md): An astronaut builds whole frameworks and meta-models, while speculative generality is one abstraction built for variation with no evidence of arriving.

Violated by
Prefer abstract frameworks, taxonomies, meta-models, and generic engines over concrete user, domain, and operational needs.

Detected by
generic_platform_before_product_need, few_real_consumers, high_framework_workaround_count

Measured by
generic components with few real consumers

Refactored by
anchor_to_use_cases, prove_with_vertical_slice, delete_unused_generality, measure_delivery_cost

Enforced by
design review against real use cases

Before

```typescript
class AbstractFooMetaStrategyOrchestrationEngineFactory {}
```

After

```typescript
class CreateFoo { execute(input: CreateFooInput): Foo {} }
```

How it is checked

Checked by
design review against real use cases

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Architecture Astronaut](https://banes-lab.com/records/architecture/architecture-astronaut.md)

### Feature-Only Design

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [security_governance](https://banes-lab.com/records/force/security-governance.md), [performance_scaling](https://banes-lab.com/records/force/performance-scaling.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which architecture serves immediate features while its quality attributes go unaddressed.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Quality Attributes](https://banes-lab.com/records/architecture/quality-attributes.md)

Violated by
Optimize architecture for immediate feature delivery while ignoring quality attributes such as security, operability, scalability, maintainability, and evolvability.

Detected by
no_SLOs, no_security_review, no_operability_requirements, quality_attribute_absent_from_ADR

Measured by
quality attributes absent from decisions, services without SLOs

Refactored by
define_quality_scenarios, add_fitness_functions, [architecture_review](https://banes-lab.com/records/architecture/architecture-review.md), risk_register

Enforced by
architecture review with quality scenarios, SLO gates

Before

```typescript
function addFooFeature() { hack(); patch(); bypassLint(); }
```

After

```typescript
function addFooFeature(input: CreateFooInput) { return createFoo.execute(input); }
```

How it is checked

Checked by
architecture review with quality scenarios, SLO gates

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Feature-Only Design](https://banes-lab.com/records/architecture/feature-only-design.md)

### Test Pyramid Inversion

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which a test suite relies mainly on slow end-to-end tests, with few unit and contract tests.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Testability](https://banes-lab.com/records/architecture/testability.md)

Violated by
Rely mainly on slow, brittle end-to-end tests while unit, contract, component, and property tests are sparse.

Detected by
high_E2E_ratio, slow_CI, flaky_integration_tests, low_unit_contract_coverage

Measured by
share of end-to-end tests, suite duration

Refactored by
add_unit_tests, contract_tests, component_tests, property_tests, reduce_E2E_scope

Enforced by
test-suite composition review, limits on CI duration

Before

```typescript
test.e2e("create foo", fullBrowserFlow);
test.e2e("rename foo", fullBrowserFlow);
test.e2e("delete foo", fullBrowserFlow);
```

After

```typescript
test.unit("FooValidator rejects an empty name", () => expect(() => validateFoo({ name: "" })).toThrow());
test.integration("FooRepository persists a Foo", async () => {
await fooRepository.save(foo);
expect(await fooRepository.find(foo.id)).toEqual(foo);
});
test.e2e("the critical signup path", criticalPathOnly);
```

How it is checked

Checked by
test-suite composition review, limits on CI duration

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Test Pyramid Inversion](https://banes-lab.com/records/architecture/test-pyramid-inversion.md)

### Mock Mirage

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md), [observability_traceability](https://banes-lab.com/records/force/observability-traceability.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which tests assert calls on mocks rather than observable behavior or contracts.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Specification-Based Testing](https://banes-lab.com/records/architecture/specification-based-testing.md)

Violated by
Overuse mocks so tests verify internal calls rather than observable behavior or contracts.

Detected by
tests_fail_on_refactor_without_behavior_change, assert_called_everywhere, no_contract_tests

Measured by
tests that break on refactors with no change in behavior

Refactored by
test_observable_behavior, contract_test, use_fake_at_boundary, reduce_internal_mocks

Enforced by
contract tests, review of mock usage

Before

```typescript
const store = { save: fn(), find: fn().returns(foo) };
```

After

```typescript
const store = new InMemoryFooStore();
runFooStoreContract(store);
```

How it is checked

Checked by
contract tests, review of mock usage

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Mock Mirage](https://banes-lab.com/records/architecture/mock-mirage.md)

### Flaky Test Normalization

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [semantic_consistency](https://banes-lab.com/records/force/semantic-consistency.md), [correctness_verification](https://banes-lab.com/records/force/correctness-verification.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which intermittent test failures are accepted and rerun until they pass.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Reproducibility](https://banes-lab.com/records/architecture/reproducibility.md)

Violated by
Accept intermittent test failures as normal and rerun until green instead of fixing nondeterminism or isolation defects.

Detected by
rerun_to_pass, quarantined_tests_never_fixed, time_order_random_test_failures

Measured by
rerun rate, quarantined tests past their fix date

Refactored by
isolate_state, control_time_randomness, fix_race, remove_external_dependency

Enforced by
a CI policy that fails on a retried test and tracks every quarantined one

Before

```typescript
test.retry(5)("foo works sometimes", async () => { await sleep(random()); expect(await getFoo()).toBeTruthy(); });
```

After

```typescript
test("foo is created deterministically", async () => { const foo = await createFoo.execute(input); expect(foo.id).toBe(expectedId); });
```

How it is checked

Checked by
a CI policy that fails on a retried test and tracks every quarantined one

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Flaky Test Normalization](https://banes-lab.com/records/architecture/flaky-test-normalization.md)

### Prompt Sprawl

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [contract_compatibility](https://banes-lab.com/records/force/contract-compatibility.md), [model_governance](https://banes-lab.com/records/force/model-governance.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which prompts, model parameters and output schemas are scattered through code without versions or evaluation.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Prompt Engineering](https://banes-lab.com/records/architecture/prompt-engineering.md)

Violated by
Scatter prompts, retrieval rules, model parameters, safety instructions, and output schemas across code without versioning, evaluation, or ownership.

Detected by
prompt_literals_in_many_files, no_prompt_registry, no_eval_for_prompt_change, model_params_scattered

Measured by
prompt literals outside the registry

Refactored by
prompt_registry, version_prompt, add_eval_suite, centralize_model_config

Enforced by
a prompt registry, with an evaluation required on every change

Before

```typescript
const a = model.run("summarize this foo: " + foo);
const b = model.run("pls summarize foo " + foo);
```

After

```typescript
const summary = model.run(FOO_PROMPTS.summarize({ foo }));
```

How it is checked

Checked by
a prompt registry, with an evaluation required on every change

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Prompt Sprawl](https://banes-lab.com/records/architecture/prompt-sprawl.md)

### Ungrounded Content

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [model_governance](https://banes-lab.com/records/force/model-governance.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which the model produces answers or decisions without retrieved evidence or disclosed uncertainty.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Agentic Architecture](https://banes-lab.com/records/architecture/agentic-architecture.md)

Contracts
[Agent Creator Kernel](https://banes-lab.com/records/algorithms/agent-creator-kernel.md)

Violated by
Generate answers, classifications, plans, or decisions without evidence retrieval, source references, confidence limits, or unsupported-claim handling.

Detected by
answer_without_sources_when_sources_required, no_retrieval_trace, unsupported_claims, confidence_not_disclosed

Measured by
answers without a source where one is required

Refactored by
RAG_boundary, evidence_citation, claim_validation, abstain_or_disclose_uncertainty

Enforced by
retrieval evaluation, claim validation against the retrieved sources

Before

```typescript
const answer = await model.run(question);
return answer;
```

After

```typescript
const context = await retrieve(question);
const answer = await model.run(FOO_PROMPTS.answer({ question, context }));
return withCitations(answer, context);
```

How it is checked

Checked by
retrieval evaluation, claim validation against the retrieved sources

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Ungrounded Content](https://banes-lab.com/records/architecture/ungrounded-content.md)

### Model Version Ambiguity

- Kind: [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- Category: [anti-patterns](https://banes-lab.com/ontology/principles/architecture-category-anti-patterns.md)
- Severity: [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- Scope: [model_governance](https://banes-lab.com/records/force/model-governance.md)
- Layer: [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)

Details

Definition
A defect in which models, prompts or indexes are used without recording their version and configuration.

Requires
none

Reinforces
none

Enables
none

In tension with
none

Conflicts with
none

Referenced by
[Model Governance](https://banes-lab.com/records/architecture/model-governance.md)

Violated by
Use models, embeddings, prompts, or evaluation artifacts without recording version, configuration, dataset, or inference context.

Detected by
model_name_missing_version, embedding_index_unversioned, eval_results_without_config, prompt_not_versioned

Measured by
inferences logged without a model version

Refactored by
[model_registry](https://banes-lab.com/records/lexicon/model-registry.md), version_prompt_dataset_index, record_inference_context, governance_log

Enforced by
a model registry, inference logging that requires a version

Before

```typescript
const result = await model.run(prompt);
```

After

```typescript
const result = await model.run(prompt, { model: "foo-llm-2024-06", temperature: 0 });
logger.info("foo.inference", { model: result.model });
```

How it is checked

Checked by
a model registry, inference logging that requires a version

Population
Every module, boundary and change the anti-pattern's detection signals scan

Freshness
A verdict stands until the scanned code or the enforcing rule changes

Refusal
The enforcing check fails the gate on a new instance, so a closed decay path cannot re-enter

Observation
The detection signals the record lists, read from source or from runtime telemetry as each signal requires

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The principle the anti-pattern conflicts with, which the enforcing check holds new code to

Depends on
Not answered

Shape it refuses
[Model Version Ambiguity](https://banes-lab.com/records/architecture/model-version-ambiguity.md)

## Links to

- [anti-pattern](https://banes-lab.com/records/kind/anti-pattern.md)
- [discouraged](https://banes-lab.com/records/vocabulary/severity-discouraged.md)
- [Modularity](https://banes-lab.com/records/force/modularity.md)
- [State transaction](https://banes-lab.com/records/force/state-transaction.md)
- [Enforcement Core](https://banes-lab.com/records/layer/enforcement-core.md)
- [Modularity](https://banes-lab.com/records/architecture/modularity.md)
- [Component-Based Architecture](https://banes-lab.com/records/architecture/component-based-architecture.md)
- [<Architecture Anti-Pattern>](https://banes-lab.com/records/algorithms/architecture-anti-pattern.md)
- [Circular Dependency](https://banes-lab.com/records/architecture/circular-dependency.md)
- [Big Ball of Mud](https://banes-lab.com/records/architecture/big-ball-of-mud.md)
- [Semantic consistency](https://banes-lab.com/records/force/semantic-consistency.md)
- [Domain boundary](https://banes-lab.com/records/force/domain-boundary.md)
- [Control coordination](https://banes-lab.com/records/force/control-coordination.md)
- [Single Responsibility Principle](https://banes-lab.com/records/architecture/single-responsibility.md)
- [High Cohesion](https://banes-lab.com/records/architecture/high-cohesion.md)
- [Divergent Change](https://banes-lab.com/records/architecture/divergent-change.md)
- [Shotgun Surgery](https://banes-lab.com/records/architecture/shotgun-surgery.md)
- [Utility Dump](https://banes-lab.com/records/architecture/utility-dump.md)
- [Fan-In](https://banes-lab.com/records/lexicon/fan-in.md)
- [Design Review](https://banes-lab.com/records/architecture/design-review.md)
- [God Object](https://banes-lab.com/records/architecture/god-object.md)
- [Interface-Based Design](https://banes-lab.com/records/architecture/interface-based-design.md)
- [Abstraction](https://banes-lab.com/records/architecture/abstraction.md)
- [Replaceability](https://banes-lab.com/records/architecture/replaceability.md)
- [Middle Man](https://banes-lab.com/records/architecture/middle-man.md)
- [Concrete Coupling](https://banes-lab.com/records/architecture/concrete-coupling.md)
- [Contract compatibility](https://banes-lab.com/records/force/contract-compatibility.md)
- [Security governance](https://banes-lab.com/records/force/security-governance.md)
- [Model governance](https://banes-lab.com/records/force/model-governance.md)
- [Data Contract](https://banes-lab.com/records/architecture/data-contract.md)
- [Canonical Schema](https://banes-lab.com/records/architecture/canonical-schema.md)
- [Schema Drift](https://banes-lab.com/records/architecture/schema-drift.md)
- [Causality ordering](https://banes-lab.com/records/force/causality-ordering.md)
- [Explicit Contracts](https://banes-lab.com/records/architecture/explicit-contracts.md)
- [Implicit Contract](https://banes-lab.com/records/architecture/implicit-contract.md)
- [Configuration Externalization](https://banes-lab.com/records/architecture/configuration-externalization.md)
- [Declarative Configuration](https://banes-lab.com/records/architecture/declarative-configuration.md)
- [Hardcoded Configuration](https://banes-lab.com/records/architecture/hardcoded-configuration.md)
- [Immutability](https://banes-lab.com/records/architecture/immutability.md)
- [State Isolation](https://banes-lab.com/records/architecture/state-isolation.md)
- [Shared Mutable State](https://banes-lab.com/records/architecture/shared-mutable-state.md)
- [Explicit Boundaries](https://banes-lab.com/records/architecture/explicit-boundaries.md)
- [Boundary Leakage](https://banes-lab.com/records/architecture/boundary-leakage.md)
- [Correctness verification](https://banes-lab.com/records/force/correctness-verification.md)
- [Policy as Code](https://banes-lab.com/records/architecture/policy-as-code.md)
- [Quality Governance Loop](https://banes-lab.com/records/algorithms/quality-governance-loop.md)
- [Manual-Only Governance](https://banes-lab.com/records/architecture/manual-only-governance.md)
- [Runtime extensibility](https://banes-lab.com/records/force/runtime-extensibility.md)
- [Metaprogramming modeling](https://banes-lab.com/records/force/metaprogramming-modeling.md)
- [Introspection](https://banes-lab.com/records/architecture/introspection.md)
- [Opaque Runtime Behavior](https://banes-lab.com/records/architecture/opaque-runtime-behavior.md)
- [Architecture evolution](https://banes-lab.com/records/force/architecture-evolution.md)
- [Risk Management](https://banes-lab.com/records/architecture/risk-management.md)
- [Unowned Risk](https://banes-lab.com/records/architecture/unowned-risk.md)
- [Observability](https://banes-lab.com/records/architecture/observability.md)
- [Unobservable Failure](https://banes-lab.com/records/architecture/unobservable-failure.md)
- [Event messaging](https://banes-lab.com/records/force/event-messaging.md)
- [Consumer-Driven Contracts](https://banes-lab.com/records/architecture/consumer-driven-contracts.md)
- [Unversioned Breaking Change](https://banes-lab.com/records/architecture/unversioned-breaking-change.md)
- [Microservices](https://banes-lab.com/records/architecture/microservices.md)
- [Shared Database](https://banes-lab.com/records/lexicon/shared-database.md)
- [Distributed Monolith](https://banes-lab.com/records/architecture/distributed-monolith.md)
- [Encapsulation](https://banes-lab.com/records/architecture/encapsulation.md)
- [Feature Envy](https://banes-lab.com/records/architecture/feature-envy.md)
- [Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md)
- [Message Chain](https://banes-lab.com/records/architecture/message-chain.md)
- [Inappropriate Intimacy](https://banes-lab.com/records/architecture/inappropriate-intimacy.md)
- [Value Object](https://banes-lab.com/records/architecture/value-object.md)
- [Long Parameter List](https://banes-lab.com/records/architecture/long-parameter-list.md)
- [Data Clumps](https://banes-lab.com/records/architecture/data-clumps.md)
- [Primitive Obsession](https://banes-lab.com/records/architecture/primitive-obsession.md)
- [Type Safety](https://banes-lab.com/records/architecture/type-safety.md)
- [Stringly Typed Programming](https://banes-lab.com/records/architecture/stringly-typed-programming.md)
- [Intent-Revealing Interface](https://banes-lab.com/records/architecture/intent-revealing-interface.md)
- [Boolean Trap](https://banes-lab.com/records/architecture/boolean-trap.md)
- [Object creation](https://banes-lab.com/records/force/object-creation.md)
- [Single Source of Truth](https://banes-lab.com/records/architecture/single-source-of-truth.md)
- [Magic Value](https://banes-lab.com/records/architecture/magic-value.md)
- [Minimum Viable Architecture](https://banes-lab.com/records/architecture/minimum-viable-architecture.md)
- [Speculative Generality](https://banes-lab.com/records/architecture/speculative-generality.md)
- [Evolutionary Architecture](https://banes-lab.com/records/architecture/evolutionary-architecture.md)
- [Pattern Distiller Kernel](https://banes-lab.com/records/algorithms/pattern-distiller-kernel.md)
- [Zombie Code](https://banes-lab.com/records/architecture/zombie-code.md)
- [Premature Abstraction](https://banes-lab.com/records/architecture/premature-abstraction.md)
- [Over-Abstraction](https://banes-lab.com/records/architecture/over-abstraction.md)
- [First-Principles Design](https://banes-lab.com/records/architecture/first-principles-design.md)
- [Golden Hammer](https://banes-lab.com/records/architecture/golden-hammer.md)
- [Pattern Cargo Cult](https://banes-lab.com/records/architecture/pattern-cargo-cult.md)
- [Lava Flow](https://banes-lab.com/records/architecture/lava-flow.md)
- [Statelessness](https://banes-lab.com/records/architecture/statelessness.md)
- [Temporal Coupling](https://banes-lab.com/records/architecture/temporal-coupling.md)
- [Principle of Least Surprise](https://banes-lab.com/records/architecture/principle-of-least-surprise.md)
- [Controlled Side Effects](https://banes-lab.com/records/architecture/controlled-side-effects.md)
- [Action at a Distance](https://banes-lab.com/records/architecture/action-at-a-distance.md)
- [Hidden Side Effect](https://banes-lab.com/records/architecture/hidden-side-effect.md)
- [Dependency Injection](https://banes-lab.com/records/architecture/dependency-injection.md)
- [Ambient Context](https://banes-lab.com/records/architecture/ambient-context.md)
- [Semantic Consistency](https://banes-lab.com/records/architecture/semantic-consistency.md)
- [Error Boundary](https://banes-lab.com/records/algorithms/error-boundary.md)
- [Inconsistent Error Model](https://banes-lab.com/records/architecture/inconsistent-error-model.md)
- [Error Handling](https://banes-lab.com/records/architecture/error-handling.md)
- [Exception Control Flow](https://banes-lab.com/records/architecture/exception-control-flow.md)
- [Null Object Pattern](https://banes-lab.com/records/architecture/null-object-pattern.md)
- [Null Semantics Drift](https://banes-lab.com/records/architecture/null-semantics-drift.md)
- [Aggregate](https://banes-lab.com/records/architecture/aggregate.md)
- [Entity](https://banes-lab.com/records/architecture/entity.md)
- [Anemic Domain Model](https://banes-lab.com/records/architecture/anemic-domain-model.md)
- [Domain Service](https://banes-lab.com/records/architecture/domain-service.md)
- [Transaction Script Sprawl](https://banes-lab.com/records/architecture/transaction-script-sprawl.md)
- [Fat Controller](https://banes-lab.com/records/architecture/fat-controller.md)
- [Interface Segregation Principle](https://banes-lab.com/records/architecture/interface-segregation.md)
- [Repository Dump](https://banes-lab.com/records/architecture/repository-dump.md)
- [Ports and Adapters Architecture](https://banes-lab.com/records/architecture/ports-and-adapters-architecture.md)
- [Framework Leakage](https://banes-lab.com/records/architecture/framework-leakage.md)
- [Anti-Corruption Layer](https://banes-lab.com/records/architecture/anti-corruption-layer.md)
- [Vendor Lock-In Leakage](https://banes-lab.com/records/architecture/vendor-lock-in-leakage.md)
- [Directed Acyclic Graph](https://banes-lab.com/records/architecture/directed-acyclic-graph.md)
- [Autonomy](https://banes-lab.com/records/architecture/autonomy.md)
- [Cyclic Deployment Dependency](https://banes-lab.com/records/architecture/cyclic-deployment-dependency.md)
- [Asynchronous Communication](https://banes-lab.com/records/architecture/asynchronous-communication.md)
- [Synchronous Chain Trap](https://banes-lab.com/records/architecture/synchronous-chain-trap.md)
- [Uniform Interface](https://banes-lab.com/records/architecture/uniform-interface.md)
- [Chatty Interface](https://banes-lab.com/records/architecture/chatty-interface.md)
- [Algorithmic Efficiency](https://banes-lab.com/records/architecture/algorithmic-efficiency.md)
- [N Plus One Query](https://banes-lab.com/records/architecture/n-plus-one-query.md)
- [Caching](https://banes-lab.com/records/architecture/caching.md)
- [Cache Poisoning by Design](https://banes-lab.com/records/architecture/cache-poisoning-by-design.md)
- [Resilience recovery](https://banes-lab.com/records/force/resilience-recovery.md)
- [Circuit Breaker Pattern](https://banes-lab.com/records/architecture/circuit-breaker-pattern.md)
- [Retry Storm](https://banes-lab.com/records/architecture/retry-storm.md)
- [Timeout Pattern](https://banes-lab.com/records/architecture/timeout-pattern.md)
- [Timeout Omission](https://banes-lab.com/records/architecture/timeout-omission.md)
- [Backpressure](https://banes-lab.com/records/architecture/backpressure.md)
- [Missing Backpressure](https://banes-lab.com/records/architecture/missing-backpressure.md)
- [Fail Fast](https://banes-lab.com/records/architecture/fail-fast.md)
- [Silent Data Corruption](https://banes-lab.com/records/architecture/silent-data-corruption.md)
- [Write Barrier](https://banes-lab.com/records/architecture/write-barrier.md)
- [Concurrency Control](https://banes-lab.com/records/architecture/concurrency-control.md)
- [Optimistic Locking](https://banes-lab.com/records/architecture/optimistic-locking.md)
- [Pessimistic Locking](https://banes-lab.com/records/architecture/pessimistic-locking.md)
- [Lost Update](https://banes-lab.com/records/architecture/lost-update.md)
- [Outbox Pattern](https://banes-lab.com/records/architecture/outbox-pattern.md)
- [Saga](https://banes-lab.com/records/lexicon/saga.md)
- [Idempotent Consumer](https://banes-lab.com/records/architecture/idempotent-consumer.md)
- [Dual Write](https://banes-lab.com/records/architecture/dual-write.md)
- [Causal Consistency](https://banes-lab.com/records/architecture/causal-consistency.md)
- [Read-Your-Writes Violation](https://banes-lab.com/records/architecture/read-your-writes-violation.md)
- [Threat Modeling](https://banes-lab.com/records/architecture/threat-modeling.md)
- [Security Theater](https://banes-lab.com/records/architecture/security-theater.md)
- [Authorization](https://banes-lab.com/records/architecture/authorization.md)
- [Authorization Scattering](https://banes-lab.com/records/architecture/authorization-scattering.md)
- [Secrets Management](https://banes-lab.com/records/architecture/secrets-management.md)
- [Secret Sprawl](https://banes-lab.com/records/architecture/secret-sprawl.md)
- [Privacy by Design](https://banes-lab.com/records/architecture/privacy-by-design.md)
- [Data Minimization](https://banes-lab.com/records/lexicon/data-minimization.md)
- [Personal Data Oversharing](https://banes-lab.com/records/architecture/personal-data-oversharing.md)
- [Observability traceability](https://banes-lab.com/records/force/observability-traceability.md)
- [Alerting](https://banes-lab.com/records/architecture/alerting.md)
- [Observability Noise](https://banes-lab.com/records/architecture/observability-noise.md)
- [Logging](https://banes-lab.com/records/architecture/logging.md)
- [Log-as-Control-Flow](https://banes-lab.com/records/architecture/log-as-control-flow.md)
- [Self-Healing Architecture](https://banes-lab.com/records/architecture/self-healing-architecture.md)
- [Auto-Remediation](https://banes-lab.com/records/architecture/auto-remediation.md)
- [Manual Runbook Dependency](https://banes-lab.com/records/architecture/manual-runbook-dependency.md)
- [Canary Deployment](https://banes-lab.com/records/architecture/canary-deployment.md)
- [Big-Bang Release](https://banes-lab.com/records/architecture/big-bang-release.md)
- [Rollback](https://banes-lab.com/records/architecture/rollback.md)
- [Irreversible Migration](https://banes-lab.com/records/architecture/irreversible-migration.md)
- [Fitness Functions](https://banes-lab.com/records/architecture/fitness-functions.md)
- [Big-Upfront Frozen Architecture](https://banes-lab.com/records/architecture/big-upfront-frozen-architecture.md)
- [Architecture Astronaut](https://banes-lab.com/records/architecture/architecture-astronaut.md)
- [Performance scaling](https://banes-lab.com/records/force/performance-scaling.md)
- [Quality Attributes](https://banes-lab.com/records/architecture/quality-attributes.md)
- [Architecture Review](https://banes-lab.com/records/architecture/architecture-review.md)
- [Feature-Only Design](https://banes-lab.com/records/architecture/feature-only-design.md)
- [Testability](https://banes-lab.com/records/architecture/testability.md)
- [Test Pyramid Inversion](https://banes-lab.com/records/architecture/test-pyramid-inversion.md)
- [Specification-Based Testing](https://banes-lab.com/records/architecture/specification-based-testing.md)
- [Mock Mirage](https://banes-lab.com/records/architecture/mock-mirage.md)
- [Reproducibility](https://banes-lab.com/records/architecture/reproducibility.md)
- [Flaky Test Normalization](https://banes-lab.com/records/architecture/flaky-test-normalization.md)
- [Prompt Engineering](https://banes-lab.com/records/architecture/prompt-engineering.md)
- [Prompt Sprawl](https://banes-lab.com/records/architecture/prompt-sprawl.md)
- [Agentic Architecture](https://banes-lab.com/records/architecture/agentic-architecture.md)
- [Agent Creator Kernel](https://banes-lab.com/records/algorithms/agent-creator-kernel.md)
- [Ungrounded Content](https://banes-lab.com/records/architecture/ungrounded-content.md)
- [Model Governance](https://banes-lab.com/records/architecture/model-governance.md)
- [Model Registry](https://banes-lab.com/records/lexicon/model-registry.md)
- [Model Version Ambiguity](https://banes-lab.com/records/architecture/model-version-ambiguity.md)

## Linked from

- [The layer topology](https://banes-lab.com/ontology/schema/the-layer-topology.md)
- [The membership](https://banes-lab.com/ontology/schema/the-membership.md)
