Skip to content

21 Ontology.Principles

Varietyz edited this page Oct 5, 2026 · 4 revisions

Ontology — Bane's Lab

The ontology holds every architectural principle with its relations and repairs, the lexicon of terms, the algorithm contracts, the reasoning spine, the layers and the resolved tensions, and the page renders it from the same data the quality tooling reads.

Canonical: https://banes-lab.com/ontology

The Ontology

The ontology is a queryable canon of software architecture. It holds every principle with its relations and its repair, every term with its definition, every algorithm with its contract, the reasoning that derives them, the layers they live in and how every tension between them is resolved, and every reference from one record to another is a link.

Principles

476 of 476 shown

Sections

Anti-patterns

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.

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"]
Loading

Big Ball of Mud

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, Component-Based Architecture, Monolith Architecture

Contracts

Formed 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, 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 Module Boundaries, Split Module, Architecture Test, Assign Owner, Fitness Functions

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

Before

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

After

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

God Object

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), High Cohesion

Distinct from Divergent Change: 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: A god object concentrates responsibilities in one place, while shotgun surgery scatters one responsibility across many.

Distinct from Utility Dump: A god object is a domain object that absorbs every change, while a utility dump is a generic helper module that no one owns.

Formed 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, distinct reasons to change

Refactored by Extract Class, Move Behavior to Its Owner, Domain Service, Facade Pattern

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

Before

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

After

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

Concrete Coupling

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, Abstraction, Replaceability, Dependency Inversion Principle (DIP)

Distinct from Middle Man: Concrete coupling depends on an implementation instead of an abstraction, while a middle man is a layer of indirection that adds nothing.

Formed 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, Dependency Injection, Invert Dependency

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

Refused by rules concrete-coupling

Before

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

After

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

Schema Drift

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, Canonical Schema

Formed 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 Contract, Versioning, Contract Testing, Schema Registry, Schema Validation

Enforced by schema registry, compatibility tests in the build

Before

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

After

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

Implicit Contract

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

Formed 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 Define Contract, Precondition Check, Postcondition Check, Schema Validation, Contract Testing

Enforced by contract tests, schema validation at public boundaries

Before

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

After

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

Hardcoded Configuration

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, Declarative Configuration

Formed 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, Configuration Schema, Centralized Configuration, Remove Secret from Code

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

Before

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

After

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

Shared Mutable State

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, State Isolation

Formed 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, Introduce Transaction Boundary, Apply Concurrency Control

Enforced by immutability and visibility lint rules, concurrency tests

Before

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

After

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

Boundary Leakage

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

Formed 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 Boundary DTO, Extract Adapter, Facade Pattern, Architecture Test

Enforced by export and import restrictions, boundary architecture tests

Before

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

After

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

Manual-Only Governance

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

Contracts Quality Governance Loop

Formed 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 Fitness Functions, Static Analysis, Policy as Code, Architecture Test, Track Rule Metrics

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

Before

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

After

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

Opaque Runtime Behavior

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

Formed 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 Manifest-Based Design, Binding Decision Log, Runtime Topology Report, Declare Capability, Discovery Validation

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

Before

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

After

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

Unowned Risk

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

Formed 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, Severity Classification, Mitigation Plan, Accepted Risk Record, Scheduled Review

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

Before

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

After

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

Unobservable Failure

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

Formed 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 Error Boundaries, Structured Log, Metrics, Alert on Critical Failure, Trace Span, Audit Logging

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

Before

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

After

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

Unversioned Breaking Change

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

Formed 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 Version Bump, Compatibility Adapter, Gradual Deprecation, Contract Testing, Migration Guide

Enforced by API and schema diff gates in the release pipeline

Before

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

After

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

Distributed Monolith

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

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

Detected by shared_database, 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 Contract, Domain Events, Outbox Pattern, Split Bounded Context, Backward-Compatible Change

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

Before

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

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

Shotgun Surgery

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

Formed 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 the Rule, Extract Module, Move Behavior to Its Owner

Enforced by duplication detection, change-coupling review

Before

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

After

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

Divergent Change

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)

Formed 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, Move Behavior to Its Owner

Enforced by module cohesion limits, design review

Before

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

After

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

Feature Envy

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

Formed 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 Behavior to Its Owner, Encapsulate State, Move Logic to the Domain, Extract Use Case

Enforced by coupling analysis in lint, design review

Before

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

After

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

Inappropriate Intimacy

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

Distinct from Message Chain: Inappropriate intimacy reads another module's internals, while a message chain navigates a chain of public references.

Formed 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 Restrict Exports, Define Contract, Facade Pattern

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

Before

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

After

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

Message Chain

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

Formed 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, Move Behavior to Its Owner

Enforced by a lint rule on member-access chain depth

Before

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

After

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

Middle Man

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

Formed 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 Collapse Layers, Inline Abstraction, Facade Pattern

Enforced by delegation-ratio analysis, design review

Before

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

After

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

Data Clumps

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

Distinct from Long Parameter List: Data clumps are one group of values traveling together unnamed, while a long parameter list is one signature with too many parameters of any kind.

Formed 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 Value Object, Introduce Boundary DTO, Name the Concept, Validate as a Group

Enforced by duplicate parameter-group detection in lint

Before

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

After

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

Primitive Obsession

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

Distinct from Data Clumps: 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: Primitive obsession is about the type of one value, while a long parameter list is about the number of parameters in one signature.

Formed 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 Value Object, Narrow Type, Replace Boolean with Enum, Encapsulate Validation

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

Before

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

After

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

Stringly Typed Programming

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

Formed 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 Replace Boolean with Enum, Introduce Discriminated Union, Centralize the Rule, Schema Validation

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

Before

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

After

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

Boolean Trap

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

Formed 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 Parameter Object, Name the Concept

Enforced by a lint rule against positional boolean parameters

Refused by rules boolean-trap

Before

createFoo(true, false, true);

After

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

Long Parameter List

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

Formed 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 Pattern, Value Object, Dependency Injection

Enforced by a lint rule on parameter count

Before

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

After

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

Magic Value

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

Formed 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 the Rule, Externalize Configuration, Name the Concept

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

Before

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

After

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

Speculative Generality

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

Formed 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, Defer Generalization, Minimum Viable Architecture

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

Before

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

After

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

Premature Abstraction

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

Contracts Pattern Distiller Kernel

Distinct from Zombie Code: Premature abstraction extracts shared code too early, while zombie code leaves dead code in place.

Formed 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 the Pattern Stabilizes, Split Abstraction, Defer Generalization

Enforced by design review against evidence of recurrence

Before

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

After

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

Over-Abstraction

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

Distinct from Speculative Generality: Over-abstraction is the state of having more layers than variation, while speculative generality is the cause, building for variation not yet seen.

Formed 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 Abstraction, Preserve Only Real Boundaries

Enforced by abstraction-ratio analysis, design review

Before

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

After

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

Golden Hammer

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

Formed 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, Trade-Off Matrix, Decision Record with Alternatives, Contextual Pattern Selection

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

Before

const config = parseFooConfig(runRegexOverEverything(rawYaml));

After

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

Pattern Cargo Cult

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

Distinct from Golden Hammer: A cargo cult copies a pattern's shape without its forces, while a golden hammer applies one familiar solution to every problem.

Formed 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, Define Contract, Name the Concept, Remove Pattern Shell

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

Before

class FooSingletonFactoryObserverProxy {}

After

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

Lava Flow

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

Distinct from Premature Abstraction: Lava flow is obsolete code kept too long, while premature abstraction is shared code extracted too early.

Distinct from Zombie Code: Lava flow is code that may still run and whose purpose nobody records, while zombie code is unreachable or disabled.

Formed 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, Assign Owner, Deprecation Plan, Delete After Evidence

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

Before

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

After

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

Zombie Code

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

Formed 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 After Evidence, Archive Reference, Restrict Exports, Dead Code Check

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

Before

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

After

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

Temporal Coupling

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

Formed 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, Precondition Check

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

Before

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

After

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

Hidden Side Effect

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, Controlled Side Effects

Distinct from Action at a Distance: A hidden side effect is a query that writes, while action at a distance is one part changing behavior elsewhere through globals or listeners.

Formed 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 Separate Query from Command, Make Effects Explicit

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

Before

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

After

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

Action at a Distance

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

Formed 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, Causation Tracing, Restrict Global Mutation

Enforced by lint rules against global mutation and monkey patching

Before

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

After

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

Ambient Context

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

Formed 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

Enforced by lint rules against global context reads in business logic

Before

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

After

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

Inconsistent Error Model

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

Formed 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 Introduce Typed Result, Standard Error Contract, Error Boundaries

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

Before

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

After

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

Exception Control Flow

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

Formed 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 Introduce Typed Result, Precondition Check

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

Before

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

After

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

Null Semantics Drift

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

Formed 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, Introduce Typed Result, Canonicalization

Enforced by schema nullability rules, strict null checking

Before

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

After

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

Anemic Domain Model

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 Domain Model, Aggregate, Entity

Formed 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 Logic to the Domain, Value Object, Add Aggregate Invariant, Encapsulate State

Enforced by architecture tests that locate domain rules, design review

Before

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

After

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

Transaction Script Sprawl

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

Formed 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, Introduce Port, Move Logic to the Domain

Enforced by architecture tests on layer responsibilities, method size limits

Before

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

After

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

Fat Controller

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

Distinct from Transaction Script Sprawl: A fat controller puts business logic in the request handler, while transaction script sprawl writes business processes as procedural scripts wherever they live.

Formed 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 Logic to the Domain, Map to Domain Model

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

Before

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

After

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

Repository Dump

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)

Formed 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 Logic to the Domain, Split Repository, Introduce Port

Enforced by persistence-boundary rules, design review

Before

class FooRepository {
  findActiveFoosForBarInRegionSortedByBaz() {}
}

After

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

Utility Dump

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

Distinct from Shotgun Surgery: A utility dump gathers unrelated helpers in one module, while shotgun surgery spreads one responsibility across many files.

Formed 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 Behavior to Its Owner, Split by Domain, Value Object, Name the Concept

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

Before

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

After

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

Framework Leakage

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

Formed 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 Extract Adapter, Map to Domain Model, Introduce Port, Move Framework Outward

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

Before

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

After

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

Vendor Lock-In Leakage

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

Formed 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 Adapter, Introduce Port, Translate Errors at the Boundary, Canonical Data Model

Enforced by import rules that confine vendor packages to adapters

Before

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

After

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

Circular Dependency

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), Low Coupling

Distinct from Inappropriate Intimacy: 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: A circular dependency is a cycle between modules, while a message chain is a client walking a chain of objects.

Formed 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 Interface, Domain Events, Mediator Pattern

Enforced by a dependency-cycle check in the build

Refused by rules circular-dependency

Before

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

After

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

Cyclic Deployment Dependency

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

Formed 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 Versioning, Backward-Compatible Change, Consumer-Driven Contract Tests, Compatibility Adapter

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

Before

fooService.callsAtStartup(barService);
barService.callsAtStartup(fooService);

After

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

Synchronous Chain Trap

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

Formed 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 Coarse-Grained Endpoint, Introduce Async Event, Query Projection, Timeout Pattern, Bulkhead Pattern

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

Before

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

After

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

Chatty Interface

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

Formed 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, Query Projection, Batch Fetch

Enforced by API review, performance tests that bound call counts

Before

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

After

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

N Plus One Query

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

Formed 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, Query Projection

Enforced by query-count assertions in integration tests

Before

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

After

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

Cache Poisoning by Design

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

Formed 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 Cache Contract, Context-Keyed Cache, Cache Invalidation on Write, Versioning

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

Before

fooCache.set(request.path, response);

After

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

Retry Storm

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

Formed 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, Backoff, Jitter, Circuit Breaker Pattern, Idempotency Key

Enforced by a resilience policy that requires bounded retries with backoff and jitter

Before

while (true) {
  try {
    return await call();
  } catch {}
}

After

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

Timeout Omission

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

Formed 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 Timeout Pattern, Deadline Propagation, Cancellation, Fail Fast or Fall Back

Enforced by a lint rule that requires a timeout on outbound calls

Before

const foo = await fetch(fooUrl);

After

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

Missing Backpressure

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

Formed 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 Limiting, Load Shedding, Backpressure

Enforced by load tests, checks that every queue is configured with a bound

Before

stream.on("data", (d) => queue.push(process(d)));

After

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

Silent Data Corruption

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

Formed 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 the Boundary, Invariant Check, Reconciliation Job, Data Change Audit

Enforced by boundary validation, invariant checks, reconciliation jobs

Before

const total = Number(a) + Number(b);
save(total);

After

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

Lost Update

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, Concurrency Control

Formed 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, Pessimistic Locking, Merge Policy, Transaction Isolation Level

Enforced by optimistic-locking checks, concurrency tests

Before

const foo = await load(id);
foo.count += 1;
await save(foo);

After

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

Dual Write

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

Formed 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 Outbox Pattern, Saga Pattern, Idempotent Consumer, Reconciliation Job

Enforced by an outbox or saga, verified by integration tests

Before

await db.save(foo);
await searchIndex.add(foo);

After

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

Read-Your-Writes Violation

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

Formed 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, Cache Invalidation on Write, Consistency Contract

Enforced by consistency-contract tests that read after a write

Before

await primaryDb.write(foo);
const view = await replicaDb.read(foo.id);

After

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

Security Theater

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

Formed 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 Modeling, Server-Side Enforcement, Penetration Testing, Policy as Code

Enforced by threat-model review, penetration tests

Before

if (password.length > 0) grantFooAccess(user);

After

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

Authorization Scattering

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

Formed 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, Attribute-Based Access Control (ABAC), Role-Based Access Control (RBAC), Authorization Tests

Enforced by a policy engine, with authorization tests per endpoint

Before

if (user.role === "admin") deleteFoo();
if (user.role === "admin" || user.id === foo.owner) editFoo();

After

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

Secret Sprawl

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

Formed 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 Secrets Management, Secret Rotation, Repository Secret Scan, Least-Privilege Credential

Enforced by secret scanning in the build, a secret store

Before

const key = "sk_live_abc123";
const dbPass = "hunter2";

After

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

Personal Data Oversharing

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

Formed 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 Purpose Binding, Field Redaction, Retention Policy

Enforced by privacy review, log redaction rules

Before

logger.info("created foo", { email: user.email, ssn: user.ssn });

After

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

Observability Noise

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

Formed 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, Cardinality Reduction, Runbook Owner, Sampling and Aggregation

Enforced by alert-ownership rules, metric cardinality limits

Before

logger.info("entering loop");
for (const f of foos) logger.info("iter", f);

After

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

Log-as-Control-Flow

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

Formed 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 Introduce Typed Result, Fail Fast or Fall Back, Recovery Policy, Alert on Critical Failure

Enforced by a lint rule against catch blocks that only log

Before

try {
  await chargeFoo(foo);
} catch (error) {
  logger.error("foo.charge.failed", error);
}
shipFoo(foo);

After

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

Manual Runbook Dependency

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, Auto-Remediation

Formed 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 the Runbook, Guardrails, Precondition Check, Execution Log

Enforced by operations review of manual steps repeated across incidents

Before

const RUNBOOK = "on failure, ssh in and run restart-foo.sh";

After

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

Big-Bang Release

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

Formed 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 Toggle, Canary Deployment, Blue-Green Deployment, Rollback Plan, Small-Batch Release

Enforced by release gates that require a canary or a feature flag and a rollback plan

Before

deployEverything("foo", "bar", "baz");

After

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

Irreversible Migration

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

Formed 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 and Write, Rollback Plan

Enforced by migration review, rollback tests

Before

await db.exec("ALTER TABLE foo DROP COLUMN legacy_name");

After

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

Big-Upfront Frozen Architecture

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

Distinct from Lava Flow: Frozen architecture fixes decisions too early, while lava flow keeps obsolete code too long.

Distinct from Premature Abstraction: Frozen architecture fixes system-level decisions early, while premature abstraction extracts one shared abstraction early.

Distinct from Zombie Code: Frozen architecture is a decision made too early, while zombie code is dead code left behind.

Formed 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, Evolutionary Architecture, Fitness Functions, Decision Review

Enforced by decision records that require evidence, periodic decision review

Before

const ARCHITECTURE = designAllModulesForNextFiveYears();

After

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

Architecture Astronaut

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

Distinct from Over-Abstraction: An astronaut builds frameworks for needs that have not arrived, while over-abstraction adds layers beyond the variation that exists.

Distinct from Speculative Generality: An astronaut builds whole frameworks and meta-models, while speculative generality is one abstraction built for variation with no evidence of arriving.

Formed 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, Vertical Slice Proof, Inline Abstraction, Measure Delivery Cost

Enforced by design review against real use cases

Before

class AbstractFooMetaStrategyOrchestrationEngineFactory {}

After

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

Feature-Only Design

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

Formed 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 Quality Scenarios, Fitness Functions, Architecture Review, Risk Register

Enforced by architecture review with quality scenarios, SLO gates

Before

function addFooFeature() {
  hack();
  patch();
  bypassLint();
}

After

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

Test Pyramid Inversion

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

Formed 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 Unit Tests, Contract Testing, Component Tests, Property-Based Testing

Enforced by test-suite composition review, limits on CI duration

Before

test.e2e("create foo", fullBrowserFlow);
test.e2e("rename foo", fullBrowserFlow);
test.e2e("delete foo", fullBrowserFlow);

After

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

Mock Mirage

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

Formed 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 Testing, Fake at the Boundary

Enforced by contract tests, review of mock usage

Before

const store = { save: fn(), find: fn().returns(foo) };

After

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

Flaky Test Normalization

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

Formed 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 Test State, Inject Clock and Randomness, Fix the Race, Fake at the Boundary

Enforced by a CI policy that fails on a retried test and tracks every quarantined one

Before

test.retry(5)("foo works sometimes", async () => {
  await sleep(random());
  expect(await getFoo()).toBeTruthy();
});

After

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

Prompt Sprawl

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

Formed 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, Prompt Versioning, Evaluation Suite, Centralized Model Configuration

Enforced by a prompt registry, with an evaluation required on every change

Before

const a = model.run("summarize this foo: " + foo);
const b = model.run("pls summarize foo " + foo);

After

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

Ungrounded Content

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

Contracts Agent Creator Kernel

Formed 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 Retrieval-Augmented Generation (RAG), Evidence Citation, Claim Validation, Abstain or Disclose Uncertainty

Enforced by retrieval evaluation, claim validation against the retrieved sources

Before

const answer = await model.run(question);
return answer;

After

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

Model Version Ambiguity

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

Formed 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, Prompt Versioning, Inference Context Record, Governance Log

Enforced by a model registry, inference logging that requires a version

Before

const result = await model.run(prompt);

After

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

Domain Architecture

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.

flowchart LR
    n_domain_driven_design["Domain-Driven Design (DDD)"]
    n_domain_model["Domain Model"]
    n_bounded_context["Bounded Context"]
    n_context_mapping["Context Mapping"]
    n_anti_corruption_layer["Anti-Corruption Layer"]
    n_explicit_boundaries["Explicit Boundaries"]
    n_aggregate["Aggregate"]
    n_value_object["Value Object"]
    n_entity["Entity"]
    n_domain_service["Domain Service"]
    n_domain_driven_design --> n_bounded_context
    n_domain_driven_design --> n_domain_model
    n_bounded_context --> n_explicit_boundaries
    n_bounded_context --> n_context_mapping
    n_context_mapping --> n_bounded_context
    n_context_mapping --> n_explicit_boundaries
    n_context_mapping --> n_anti_corruption_layer
    n_aggregate --> n_explicit_boundaries
    n_entity --> n_domain_model
    n_entity -.-> n_value_object
    n_domain_service --> n_domain_model
    n_domain_service -.-> n_aggregate
Loading

Domain-Driven Design (DDD)

Details

Definition A convention of modeling software on the business domain's own language, split into bounded contexts with a domain model in each.

Requires Ubiquitous Language, Bounded Context

Reinforces Domain Model, Semantic Consistency

Enables Domain Alignment

In tension with Simple CRUD

Conflicts with Anemic Transaction Script

Referenced by Domain Events, Ubiquitous Language

Tensions Domain-Driven Design (DDD) / Simple CRUD

Distinct from Event-Driven Architecture: Domain-driven design models software on the domain's language, while event-driven architecture connects services through published events.

Violated by Anemic Domain Model, Fat Controller

Detected by anemic models, scattered business rules

Measured by domain logic locality

Refactored by Extract Domain Model, Aggregate, Split Bounded Context

Enforced by layer rules, domain tests

Before

function updateFoo(row: FooRow, name: string) {
  row.name = name;
  row.updated_at = Date.now();
  return fooTable.save(row);
}

After

class Foo {
  private constructor(
    readonly id: FooId,
    private name: string,
  ) {}
  rename(name: FooName) {
    this.name = name.value;
  }
}
foo.rename(FooName.create(name));

How it is checked

Checked by layer rules, domain tests

Population Every domain type, business rule and context boundary in the domain layer

Freshness A verdict stands until a domain type, a rule's location or a context boundary changes

Refusal The layer rule or the domain test fails when a rule or a model leaves its context or its aggregate

Observation Where each business rule and invariant is enforced, read from source and the domain tests

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 domain model, which decides the context and the aggregate every rule belongs to

Depends on Ubiquitous Language, Bounded Context, Domain Model, Semantic Consistency, Domain Alignment

Shape it refuses Anemic Transaction Script

Domain Model

Details

Definition A formal definition of the business concepts, rules and invariants of one context, written as types with behavior.

Requires Ubiquitous Language, Invariant

Reinforces Correctness, Semantic Contracts

Enables Business Rule Encapsulation

In tension with Persistence Simplicity

Conflicts with Anemic Domain Model

Referenced by Domain-Driven Design (DDD), Entity, Domain Service, Semantic Contracts, Domain Events

Tensions Domain Model / Persistence Simplicity

Violated by Anemic Domain Model

Detected by procedural domain logic in services/controllers

Measured by rule locality, invariant coverage

Refactored by Move Logic to the Domain, Value Object, Aggregate

Enforced by domain layer rules, tests

Before

type Foo = { status: string; count: number };
function closeFoo(foo: Foo) {
  foo.status = "closed";
}

After

class Foo {
  #status: "open" | "closed" = "open";
  close() {
    if (this.#status === "closed") throw new Error("Foo already closed");
    this.#status = "closed";
  }
}

How it is checked

Checked by domain layer rules, tests

Population Every domain type, business rule and context boundary in the domain layer

Freshness A verdict stands until a domain type, a rule's location or a context boundary changes

Refusal The layer rule or the domain test fails when a rule or a model leaves its context or its aggregate

Observation Where each business rule and invariant is enforced, read from source and the domain tests

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 domain model, which decides the context and the aggregate every rule belongs to

Depends on Ubiquitous Language, Invariant, Correctness, Semantic Contracts, Business Rule Encapsulation

Shape it refuses Anemic Domain Model

Bounded Context

Details

Definition A rule or precondition that each domain model holds inside one explicit boundary, where its terms have one meaning.

Requires Explicit Boundaries, Ubiquitous Language

Reinforces Modularity, Autonomy

Enables Context Mapping, Microservices

In tension with Cross-Context Reuse

Conflicts with Shared Global Model

Referenced by Domain-Driven Design (DDD), Context Mapping, Package by Feature, Microservices

Contracts Domain Modeling

Tensions Bounded Context / Cross-Context Reuse

Distinct from Relationship Semantics: A bounded context fixes meaning inside one boundary, while relationship semantics fixes the meaning of each link between boundaries.

Violated by Shared Global Model

Detected by shared domain entities across contexts

Measured by context coupling

Refactored by Split Bounded Context, Anti-Corruption Layer, Context Mapping

Enforced by package/service boundaries

Before

type FooStatus = "A" | "D";
function priceBar(status: FooStatus) {
  return status === "A" ? 10 : 0;
}

After

type FooStatus = "active" | "disabled";
type BarEligibility = "eligible" | "ineligible";
function toBarEligibility(status: FooStatus): BarEligibility {
  return status === "active" ? "eligible" : "ineligible";
}

How it is checked

Checked by package/service boundaries

Population Every domain type, business rule and context boundary in the domain layer

Freshness A verdict stands until a domain type, a rule's location or a context boundary changes

Refusal The layer rule or the domain test fails when a rule or a model leaves its context or its aggregate

Observation Where each business rule and invariant is enforced, read from source and the domain tests

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 domain model, which decides the context and the aggregate every rule belongs to

Depends on Explicit Boundaries, Ubiquitous Language, Modularity, Autonomy, Context Mapping, Microservices

Shape it refuses Shared Global Model

Context Mapping

Details

Definition The activity of recording how bounded contexts relate, including which one is upstream and how their models translate.

Requires Bounded Context, Relationship Semantics

Reinforces Explicit Boundaries, Integration Clarity

Enables Anti-Corruption Layer

In tension with Documentation Overhead

Conflicts with Implicit Integration

Referenced by Bounded Context

Tensions Context Mapping / Documentation Overhead

Violated by Implicit Integration

Detected by unclear ownership, ambiguous integration flows

Measured by undocumented dependency count

Refactored by none

Enforced by architecture docs, dependency reviews

Before

fooService.writeDirectly(barDatabase, foo);
barService.readDirectly(fooDatabase, foo.id);

After

const contextMap = {
  upstream: "FooContext",
  downstream: "BarContext",
  relationship: "published-language",
} as const;
fooEvents.publish(toBarIntegrationEvent(foo));

How it is checked

Checked by architecture docs, dependency reviews

Population Every domain type, business rule and context boundary in the domain layer

Freshness A verdict stands until a domain type, a rule's location or a context boundary changes

Refusal The layer rule or the domain test fails when a rule or a model leaves its context or its aggregate

Observation Where each business rule and invariant is enforced, read from source and the domain tests

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 domain model, which decides the context and the aggregate every rule belongs to

Depends on Bounded Context, Relationship Semantics, Explicit Boundaries, Integration Clarity, Anti-Corruption Layer

Shape it refuses Implicit Integration

Anti-Corruption Layer

Details

Definition A design pattern that translates an external system's model into the local domain's terms at the boundary.

Requires Explicit Boundary, Translation Model

Reinforces Domain Purity, Low Coupling

Enables Legacy/System Integration

In tension with Mapping Overhead

Conflicts with Vendor Lock-In Leakage

Referenced by Context Mapping, Adapter Pattern

Contracts Anti-Corruption Layer Over Cross-Context Leak

Tensions Anti-Corruption Layer / Mapping Overhead

Violated by Direct External Coupling

Detected by external DTOs used in domain layer

Measured by leakage count, adapter coverage

Refactored by Extract Adapter, Introduce Boundary DTO

Enforced by import rules, layer tests

Before

function createBar(fooResponse: FooApiResponse) {
  return barService.create({ foo_status: fooResponse.state_code });
}

After

type BarInput = { eligible: boolean };
function fromFoo(response: FooApiResponse): BarInput {
  return { eligible: response.state_code === "A" };
}
barService.create(fromFoo(fooResponse));

How it is checked

Checked by import rules, layer tests

Population Every domain type, business rule and context boundary in the domain layer

Freshness A verdict stands until a domain type, a rule's location or a context boundary changes

Refusal The layer rule or the domain test fails when a rule or a model leaves its context or its aggregate

Observation Where each business rule and invariant is enforced, read from source and the domain tests

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 domain model, which decides the context and the aggregate every rule belongs to

Depends on Explicit Boundary, Translation Model, Domain Purity, Low Coupling, Legacy/System Integration

Shape it refuses Vendor Lock-In Leakage, Vendor Lock-In Leakage

Explicit Boundaries

Details

Definition A design rule that each module declares its public interface and owner, and other modules reach it only through that interface.

Requires Stable Interfaces, Ownership

Reinforces Modularity, Encapsulation

Enables Replaceability, Governance

In tension with Cross-Cutting Concerns

Conflicts with Boundary Leakage

Referenced by Bounded Context, Context Mapping, Aggregate, Single Responsibility Principle (SRP), Separation of Concerns, High Cohesion, Modularity, Independence, Declared Jurisdiction

Tensions Explicit Boundaries / Cross-Cutting Concerns

Distinct from Declared Jurisdiction: Explicit boundaries declare a module's interface and owner, while declared jurisdiction declares which roots and files a naming gate governs.

Distinct from Abstraction: Explicit boundaries fix where one module ends, while abstraction fixes how a concept is expressed without its detail.

Distinct from Encapsulation: Explicit boundaries govern access between modules, while encapsulation governs changes to one object's state.

Distinct from Governance: Explicit boundaries are the declared interfaces, while governance holds decisions to shared policy.

Distinct from Single Source of Truth: Explicit boundaries give each module one public interface, while a single source of truth gives each fact one owning definition.

Distinct from Independence: Explicit boundaries declare the interface, while independence is testing and deploying a module without its neighbors.

Distinct from Modularity: Explicit boundaries declare each module's interface and owner, while modularity is the division into modules itself.

Distinct from Separation of Concerns: Explicit boundaries declare interfaces, while separation of concerns decides which concerns sit on each side of them.

Distinct from Single Responsibility Principle (SRP): Explicit boundaries declare interfaces, while single responsibility limits what sits behind one to one reason to change.

Violated by Boundary Leakage, Inappropriate Intimacy

Detected by forbidden imports, cyclic dependencies

Measured by boundary violation count

Refactored by Move Behavior to Its Owner, Define Contract, Restrict Exports

Enforced by module rules, architecture tests

Before

import { fooDatabase } from "../../foo/infrastructure/database";
export function loadBar(id: string) {
  return fooDatabase.query(id);
}

After

export interface FooGateway {
  find(id: FooId): Promise<FooSnapshot>;
}
export function loadBar(id: FooId, foos: FooGateway) {
  return foos.find(id);
}

How it is checked

Checked by module rules, architecture tests

Population Every domain type, business rule and context boundary in the domain layer

Freshness A verdict stands until a domain type, a rule's location or a context boundary changes

Refusal The layer rule or the domain test fails when a rule or a model leaves its context or its aggregate

Observation Where each business rule and invariant is enforced, read from source and the domain tests

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 domain model, which decides the context and the aggregate every rule belongs to

Depends on Stable Interfaces, Ownership, Modularity, Encapsulation, Replaceability, Governance

Shape it refuses Boundary Leakage

Aggregate

Details

Definition A design pattern that groups entities under one root, which is the only entry point and keeps the group's invariants.

Requires Explicit Boundaries

Reinforces Invariant, Encapsulation

Enables Transactional Consistency Boundary, Root-Guarded Invariants

In tension with Aggregate Size

Conflicts with Anemic Domain Model

Referenced by Domain Service

Tensions Aggregate / Aggregate Size

Violated by Anemic Domain Model

Detected by cross-entity invariant checks scattered in services

Measured by out-of-aggregate invariant enforcement count

Refactored by Add Aggregate Invariant

Enforced by domain model review

Before

fooOrder.total -= item.price;
fooOrderItems.delete(item.id);

After

class FooOrder {
  #items: FooItem[] = [];
  #total = 0;
  removeItem(id: FooItemId) {
    this.#items = this.#items.filter((item) => item.id !== id);
    this.#total = this.#items.reduce((sum, item) => sum + item.price, 0);
  }
}

How it is checked

Checked by domain model review

Population Every domain type, business rule and context boundary in the domain layer

Freshness A verdict stands until a domain type, a rule's location or a context boundary changes

Refusal The layer rule or the domain test fails when a rule or a model leaves its context or its aggregate

Observation Where each business rule and invariant is enforced, read from source and the domain tests

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 domain model, which decides the context and the aggregate every rule belongs to

Depends on Explicit Boundaries, Invariant, Encapsulation, Transactional Consistency Boundary, Root-Guarded Invariants

Shape it refuses Anemic Domain Model

Value Object

Details

Definition A design pattern that models a domain value as an immutable, self-validating object compared by its attributes.

Requires Value Equality

Reinforces Immutability, Encapsulation

Enables Self-Validating Values, Side-Effect-Free Equality

In tension with Object Count

Conflicts with Primitive Obsession, Data Clumps, Long Parameter List

Referenced by Entity

Tensions Value Object / Object Count

Violated by Primitive Obsession

Detected by repeated validation of the same primitive shape

Measured by primitive-typed domain concept count

Refactored by none

Enforced by domain model review

Before

function priceFoo(amount: number, currency: string) {
  return { amount, currency };
}

After

class Money {
  private constructor(
    readonly amount: number,
    readonly currency: string,
  ) {}
  static of(amount: number, currency: string): Money {
    if (amount < 0) throw new Error("negative money");
    return new Money(amount, currency);
  }
  equals(other: Money) {
    return this.amount === other.amount && this.currency === other.currency;
  }
  add(other: Money): Money {
    return Money.of(this.amount + other.amount, this.currency);
  }
}

How it is checked

Checked by domain model review

Population Every domain type, business rule and context boundary in the domain layer

Freshness A verdict stands until a domain type, a rule's location or a context boundary changes

Refusal The layer rule or the domain test fails when a rule or a model leaves its context or its aggregate

Observation Where each business rule and invariant is enforced, read from source and the domain tests

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 domain model, which decides the context and the aggregate every rule belongs to

Depends on Value Equality, Immutability, Encapsulation, Self-Validating Values, Side-Effect-Free Equality

Shape it refuses Primitive Obsession, Data Clumps, Long Parameter List

Entity

Details

Definition A design pattern that models a domain object by a stable identity, which stays the same while its attributes change.

Requires Stable Identity

Reinforces Domain Model, Encapsulation

Enables Identity-Based Equality, Lifecycle Tracking

In tension with Value Object

Conflicts with Anemic Domain Model

Tensions Entity / Value Object

Distinct from Value Object: An entity is known by an identity that outlives its attributes, while a value object is known only by its attributes.

Violated by Attribute-Compared Identity

Detected by equality by field value where identity is meant

Measured by attribute-equality misuse count

Refactored by none

Enforced by domain model review

Before

type Foo = { id: string; name: string; status: string };
foo.status = "active";

After

class Foo {
  constructor(
    readonly id: FooId,
    private name: string,
    private status: FooStatus,
  ) {}
  equals(other: Foo) {
    return this.id === other.id;
  }
  activate() {
    this.status = "active";
  }
}

How it is checked

Checked by domain model review

Population Every domain type, business rule and context boundary in the domain layer

Freshness A verdict stands until a domain type, a rule's location or a context boundary changes

Refusal The layer rule or the domain test fails when a rule or a model leaves its context or its aggregate

Observation Where each business rule and invariant is enforced, read from source and the domain tests

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 domain model, which decides the context and the aggregate every rule belongs to

Depends on Stable Identity, Domain Model, Encapsulation, Identity-Based Equality, Lifecycle Tracking

Shape it refuses Anemic Domain Model

Domain Service

Details

Definition A design pattern that places a domain rule spanning several entities in a stateless service named in the domain's language.

Requires Domain Model

Reinforces Single Responsibility Principle (SRP), Ubiquitous Language

Enables Cross-Entity Domain Logic

In tension with Aggregate

Conflicts with Fat Controller, Transaction Script Sprawl

Tensions Domain Service / Aggregate

Distinct from Aggregate: A domain service holds a stateless rule spanning entities, while an aggregate holds entities and their invariants under one root.

Violated by Fat Controller

Detected by domain logic in application/transport layers

Measured by misplaced domain-rule count

Refactored by none

Enforced by domain model review

Before

class FooAccount {
  transferTo(other: FooAccount, amount: number) {
    this.balance -= amount;
    other.balance += amount;
  }
}

After

class FooTransferService {
  transfer(from: FooAccount, to: FooAccount, amount: Money) {
    from.withdraw(amount);
    to.deposit(amount);
  }
}

How it is checked

Checked by domain model review

Population Every domain type, business rule and context boundary in the domain layer

Freshness A verdict stands until a domain type, a rule's location or a context boundary changes

Refusal The layer rule or the domain test fails when a rule or a model leaves its context or its aggregate

Observation Where each business rule and invariant is enforced, read from source and the domain tests

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 domain model, which decides the context and the aggregate every rule belongs to

Depends on Domain Model, Single Responsibility Principle (SRP), Ubiquitous Language, Cross-Entity Domain Logic

Shape it refuses Fat Controller, Transaction Script Sprawl

Runtime Discovery / Dynamic Binding

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.

flowchart LR
    n_runtime_discovery["Runtime Discovery"]
    n_service_discovery["Service Discovery"]
    n_dynamic_binding["Dynamic Binding"]
    n_dynamic_dispatch["Dynamic Dispatch"]
    n_runtime_extensibility["Runtime Extensibility"]
    n_runtime_discovery --> n_runtime_extensibility
    n_runtime_discovery --> n_service_discovery
    n_dynamic_binding --> n_runtime_extensibility
Loading

Runtime Discovery

Details

Definition A mechanism that finds the available handlers, plugins or services at startup by matching a naming convention, a file pattern or metadata, and registers each one it finds in place of a hand-written list.

Requires Metadata, Convention

Reinforces Runtime Extensibility

Enables Plugin Architecture, Service Discovery, Self-Registration

In tension with Predictability, Static Analysis, Startup Cost

Conflicts with Compile-Time Binding, Manual Registration

Referenced by Self-Describing Architecture, Metadata-Driven Design, Capability Declaration, Manifest-Based Design, Reflection

Contracts Runtime Discovery

Tensions Runtime Discovery / Predictability, Runtime Discovery / Static Analysis, Runtime Discovery / Startup Cost

Distinct from Capability Declaration: Runtime discovery finds which components exist, while a capability declaration states what each one supports.

Distinct from Introspection: Runtime discovery finds components by convention or pattern, while introspection reads one object's type and members.

Distinct from Reflection: Runtime discovery finds and registers components, while reflection reads and acts on type metadata, which discovery may use.

Distinct from Service Discovery: Runtime discovery finds in-process components at startup, while service discovery resolves a service name to a network endpoint at call time.

Distinct from Static Analysis: Runtime discovery decides the component set as the program starts, while static analysis reasons about source that has not run.

Violated by Manual Registration

Detected by manual class/service lists

Measured by discovery coverage

Refactored by Registry Pattern, Static Analysis, Manifest-Based Design

Enforced by startup validation

Before

import { FooHandler } from "./foo-handler";
import { BarHandler } from "./bar-handler";
const handlers = [new FooHandler(), new BarHandler()];

After

const modules = await discover<HandlerModule>("./handlers/*.handler.js");
const handlers = modules.map((module) => module.create());

How it is checked

Checked by startup validation

Population Every binding the runtime resolves: handlers, plugins, services, formatters and policies

Freshness A verdict stands until a registered module, a discovery pattern or the configuration changes

Refusal Startup validation or the composition-root test fails when a declared binding resolves to nothing

Observation The resolved bindings reported at startup, compared with the modules on disk and the configuration

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 modules on disk and the configuration, which the bindings reported at startup are compared against

Depends on Metadata, Convention, Runtime Extensibility, Plugin Architecture, Service Discovery, Self-Registration

Shape it refuses Compile-Time Binding, Manual Registration

Service Discovery

Details

Definition A mechanism that resolves a service name to a healthy network endpoint at call time through a registry.

Requires Service Registry, Health Checks

Reinforces Scalability, Resilience

Enables Dynamic Routing, Failover

In tension with Operational Complexity

Conflicts with Hardcoded Endpoints

Referenced by Runtime Discovery

Tensions Service Discovery / Operational Complexity

Distinct from Failover: Service discovery resolves a name to a healthy endpoint, while failover switches traffic to a standby when the active one fails.

Distinct from Health Checks: Service discovery resolves endpoints, while health checks report whether each endpoint is ready.

Distinct from Service Registry: Service discovery is the lookup at call time, while the service registry is the table the lookup reads.

Violated by Hardcoded Endpoints

Detected by hardcoded URLs, missing registry lookup

Measured by dynamic resolution coverage

Refactored by none

Enforced by config scans, deployment policy

Before

const fooUrl = "http://10.0.0.14:8080";
await http.get(`${fooUrl}/foo/${id}`);

After

const endpoint = await serviceDiscovery.resolve("foo-service");
await http.get(new URL(`/foo/${id}`, endpoint));

How it is checked

Checked by config scans, deployment policy

Population Every binding the runtime resolves: handlers, plugins, services, formatters and policies

Freshness A verdict stands until a registered module, a discovery pattern or the configuration changes

Refusal Startup validation or the composition-root test fails when a declared binding resolves to nothing

Observation The resolved bindings reported at startup, compared with the modules on disk and the configuration

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 modules on disk and the configuration, which the bindings reported at startup are compared against

Depends on Service Registry, Health Checks, Scalability, Resilience, Dynamic Routing, Failover

Shape it refuses Hardcoded Endpoints

Dynamic Binding

Details

Definition A mechanism that selects the implementation behind an interface at runtime, from configuration or a registry, so the choice is made at bootstrap or first use rather than fixed in code.

Requires Abstraction, Runtime Resolution

Reinforces Polymorphism, Extensibility, Runtime Extensibility

Enables Strategy Swap, Deferred Implementation Choice

In tension with Static Safety, Predictability, Debugging

Conflicts with Compile-Time Binding

Referenced by Capability Declaration, Reflection, Service Registry

Tensions Dynamic Binding / Static Safety, Dynamic Binding / Predictability, Dynamic Binding / Debugging

Distinct from Capability Declaration: Dynamic binding picks an implementation at runtime, while a capability declaration lists what an implementation supports so the pick can be checked.

Distinct from Polymorphism: Polymorphism lets the receiver choose the implementation per call, while dynamic binding chooses it from configuration or a registry.

Distinct from Service Registry: Dynamic binding is the choice made at runtime, while a service registry is the keyed table it can choose from.

Violated by Compile-Time Binding

Detected by hardcoded implementation selection

Measured by runtime binding coverage

Refactored by Factory Pattern, Registry, Strategy Pattern

Enforced by integration tests

Before

const formatter = new JsonFooFormatter();
formatter.format(foo);

After

const formatter = formatterRegistry.get(config.format);
if (!formatter) throw new Error(`unknown formatter: ${config.format}`);
formatter.format(foo);

How it is checked

Checked by integration tests

Population Every binding the runtime resolves: handlers, plugins, services, formatters and policies

Freshness A verdict stands until a registered module, a discovery pattern or the configuration changes

Refusal Startup validation or the composition-root test fails when a declared binding resolves to nothing

Observation The resolved bindings reported at startup, compared with the modules on disk and the configuration

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 modules on disk and the configuration, which the bindings reported at startup are compared against

Depends on Abstraction, Runtime Resolution, Polymorphism, Extensibility, Runtime Extensibility, Strategy Swap, Deferred Implementation Choice

Shape it refuses Compile-Time Binding

Dynamic Dispatch

Details

Definition A mechanism that chooses which operation runs from the receiver or a keyed table at runtime, replacing a conditional over kinds.

Requires Polymorphism

Reinforces Open/Closed Principle (OCP)

Enables Replace Conditional with Polymorphism

In tension with Traceability

Conflicts with Type Switching

Referenced by Polymorphism

Tensions Dynamic Dispatch / Traceability

Violated by Type Switching

Detected by switch/if chains on type

Measured by conditional dispatch count

Refactored by Replace Conditional with Polymorphism, Strategy Pattern

Enforced by lint rules, review

Before

function execute(kind: string, foo: Foo) {
  if (kind === "save") return saveFoo(foo);
  if (kind === "publish") return publishFoo(foo);
}

After

const commands: Record<string, (foo: Foo) => unknown> = {
  save: saveFoo,
  publish: publishFoo,
};
function execute(kind: string, foo: Foo) {
  const command = commands[kind];
  if (!command) throw new Error(`unknown command ${kind}`);
  return command(foo);
}

How it is checked

Checked by lint rules, review

Population Every binding the runtime resolves: handlers, plugins, services, formatters and policies

Freshness A verdict stands until a registered module, a discovery pattern or the configuration changes

Refusal Startup validation or the composition-root test fails when a declared binding resolves to nothing

Observation The resolved bindings reported at startup, compared with the modules on disk and the configuration

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 modules on disk and the configuration, which the bindings reported at startup are compared against

Depends on Polymorphism, Open/Closed Principle (OCP), Replace Conditional with Polymorphism

Shape it refuses Type Switching

Runtime Extensibility

Details

Definition The degree to which new capability can be added to a running system through extension points, without modifying its core.

Requires Extension Points, Stable Interfaces

Reinforces Plugin Architecture, Open/Closed Principle (OCP)

Enables Capability Addition without Core Modification

In tension with Predictability, Security

Conflicts with Closed Static Core

Referenced by Runtime Discovery, Dynamic Binding, Runtime Code Generation, Prototype Pattern, Plugin Architecture, Feature Toggle

Contracts Runtime Extensibility

Tensions Runtime Extensibility / Predictability, Runtime Extensibility / Security

Distinct from Stable Interfaces: Runtime extensibility adds capability through extension points, while stable interfaces keep those points unchanged across releases.

Distinct from Extensibility: Extensibility is adding behavior with little change to existing code, while runtime extensibility adds it to a system that is already running.

Violated by Closed Core

Detected by repeated core changes for variants

Measured by extension/core-change ratio

Refactored by Extension Points

Enforced by extension conformance tests

Before

switch (pluginName) {
  case "foo":
    return new FooPlugin();
  case "bar":
    return new BarPlugin();
}

After

export function registerPlugin(name: string, create: () => Plugin) {
  pluginRegistry.set(name, create);
}
const plugin = pluginRegistry.get(pluginName)?.();

How it is checked

Checked by extension conformance tests

Population Every binding the runtime resolves: handlers, plugins, services, formatters and policies

Freshness A verdict stands until a registered module, a discovery pattern or the configuration changes

Refusal Startup validation or the composition-root test fails when a declared binding resolves to nothing

Observation The resolved bindings reported at startup, compared with the modules on disk and the configuration

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 modules on disk and the configuration, which the bindings reported at startup are compared against

Depends on Extension Points, Stable Interfaces, Plugin Architecture, Open/Closed Principle (OCP), Capability Addition without Core Modification

Shape it refuses Closed Static Core

Causality / Ordering / Distributed Time

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.

flowchart LR
    n_causality["Causality"]
    n_causal_consistency["Causal Consistency"]
    n_happens_before_relationship["Happens-Before Relationship"]
    n_event_ordering["Event Ordering"]
    n_causal_dependency["Causal Dependency"]
    n_dependency_graph["Dependency Graph"]
    n_directed_acyclic_graph["Directed Acyclic Graph (DAG)"]
    n_vector_clocks["Vector Clocks"]
    n_lamport_clocks["Lamport Clocks"]
    n_hybrid_logical_clocks["Hybrid Logical Clocks"]
    n_crdts["CRDTs"]
    n_total_order_broadcast["Total-Order Broadcast"]
    n_cap_theorem["CAP Theorem"]
    n_pacelc_theorem["PACELC Theorem"]
    n_causality --> n_event_ordering
    n_event_ordering --> n_causality
    n_causal_dependency --> n_causality
    n_vector_clocks --> n_causal_consistency
    n_hybrid_logical_clocks --> n_happens_before_relationship
    n_hybrid_logical_clocks --> n_causal_consistency
    n_hybrid_logical_clocks --> n_event_ordering
    n_crdts --> n_causal_consistency
    n_total_order_broadcast --> n_event_ordering
    n_cap_theorem --> n_causal_consistency
    n_pacelc_theorem --> n_cap_theorem
    n_pacelc_theorem --> n_cap_theorem
Loading

Causality

Details

Definition A design rule that every effect records the event that caused it, so its order can be reasoned about.

Requires Causation Tracking

Reinforces Traceability, Event Ordering

Enables Correct Workflow Reasoning

In tension with Parallelism

Conflicts with Unordered Side Effects

Referenced by Event Ordering, Causal Dependency, Causation ID, Distributed Tracing

Contracts Causality Core

Tensions Causality / Parallelism

Violated by Unlinked Events

Detected by missing causation/correlation metadata

Measured by causal trace completeness

Refactored by Causation ID, Make Order Explicit

Enforced by event schema and workflow tests

Before

events.push({ type: "BarCreated", at: Date.now() });
events.push({ type: "FooCreated", at: Date.now() });

After

const fooCreated = append({ type: "FooCreated" });
append({ type: "BarCreated", causedBy: fooCreated.id });

How it is checked

Checked by event schema and workflow tests

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Causation Tracking, Traceability, Event Ordering, Correct Workflow Reasoning

Shape it refuses Unordered Side Effects

Causal Consistency

Details

Definition A conceptual representation of a consistency guarantee in which no reader sees an effect before its cause.

Requires Causal Ordering

Reinforces Eventual Consistency Safety

Enables User-Visible Ordering Guarantees

In tension with Latency/Availability

Conflicts with Arbitrary Reordering, Read-Your-Writes Violation

Referenced by Vector Clocks, Hybrid Logical Clocks, CRDTs, CAP Theorem

Tensions Causal Consistency / Latency/Availability

Violated by Arbitrary Reordering

Detected by order anomaly tests

Measured by causal anomaly rate

Refactored by Causation ID, Read From Primary After Write

Enforced by consistency tests

Before

replica.apply(barCreated);
replica.apply(fooCreated);

After

replica.applyWhenReady(barCreated, {
  requires: [fooCreated.id],
});
replica.apply(fooCreated);

How it is checked

Checked by consistency tests

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Causal Ordering, Eventual Consistency Safety, User-Visible Ordering Guarantees

Shape it refuses Arbitrary Reordering, Read-Your-Writes Violation

Happens-Before Relationship

Details

Definition A conceptual representation of the partial order in which one operation is known to precede another.

Requires Ordering Semantics

Reinforces Correctness, Causal Reasoning

Enables Race Detection

In tension with Parallel Execution

Conflicts with Race Conditions

Referenced by Hybrid Logical Clocks

Tensions Happens-Before Relationship / Parallel Execution

Violated by Race Conditions

Detected by race detectors, missing synchronization

Measured by ordering violation count

Refactored by Apply Concurrency Control, Make Order Explicit

Enforced by concurrency tests

Before

const a = { id: "a", at: Date.now() };
const b = { id: "b", at: Date.now() };

After

const a = { id: "a", ordinal: 1 };
const b = { id: "b", ordinal: 2, after: [a.id] };
assert(happensBefore(a, b));

How it is checked

Checked by concurrency tests

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Ordering Semantics, Correctness, Causal Reasoning, Race Detection

Shape it refuses Race Conditions

Event Ordering

Details

Definition A rule or precondition that a stateful consumer processes the events of one key in their sequence order.

Requires Ordering Key or Sequence

Reinforces Causality

Enables Correct Stateful Processing

In tension with Throughput

Conflicts with Unordered Parallel Consumption

Referenced by Causality, Hybrid Logical Clocks, Total-Order Broadcast

Tensions Event Ordering / Throughput

Distinct from Ordering Key or Sequence: Event ordering binds the consumer to process one key's events in order, while the ordering key is the field on each event that makes the order known.

Violated by Unordered Parallel Consumption

Detected by missing ordering key/sequence checks

Measured by out-of-order rate

Refactored by Partitioning, Logical Counter, Reorder Buffer

Enforced by stream config, consumer tests

Before

events.sort((a, b) => a.timestamp - b.timestamp);

After

events.sort((a, b) => a.streamOrdinal - b.streamOrdinal);

How it is checked

Checked by stream config, consumer tests

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Ordering Key or Sequence, Causality, Correct Stateful Processing

Shape it refuses Unordered Parallel Consumption

Causal Dependency

Details

Definition A conceptual representation of one step or event that cannot proceed until another has happened.

Requires Dependency Declaration

Reinforces Causality, Traceability

Enables Impact Analysis

In tension with Graph Complexity

Conflicts with Hidden Dependency

Tensions Causal Dependency / Graph Complexity

Violated by Hidden Dependency

Detected by undocumented call/event dependency

Measured by hidden dependency count

Refactored by Explicit Dependency, Causation ID

Enforced by dependency graph checks

Before

processBar(barEvent);

After

if (!projection.has(barEvent.fooEventId)) defer(barEvent);
else processBar(barEvent);

How it is checked

Checked by dependency graph checks

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Dependency Declaration, Causality, Traceability, Impact Analysis

Shape it refuses Hidden Dependency

Dependency Graph

Details

Definition Descriptive data about which modules, tasks or services depend on which, extracted as a directed graph.

Requires Dependency Extraction

Reinforces Architecture Compliance

Enables Cycle Detection, Impact Analysis

In tension with Dynamic Loading

Conflicts with Hidden Dependency

Referenced by Impact Analysis

Tensions Dependency Graph / Dynamic Loading

Violated by Hidden Dependency

Detected by graph extraction mismatch

Measured by cycle count, graph density

Refactored by Invert Dependency

Enforced by dependency graph CI checks

Before

const tasks = [loadFoo, buildBar, publishBaz];
await Promise.all(tasks.map((task) => task()));

After

const graph = new DependencyGraph();
graph.add("buildBar", { dependsOn: ["loadFoo"] });
graph.add("publishBaz", { dependsOn: ["buildBar"] });
await graph.execute();

How it is checked

Checked by dependency graph CI checks

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Dependency Extraction, Architecture Compliance, Cycle Detection, Impact Analysis

Shape it refuses Hidden Dependency

Directed Acyclic Graph (DAG)

Details

Definition A rule or precondition that every dependency points one way and the graph they form has no cycle, so its nodes can be put in topological order.

Requires none

Reinforces Layering, Build Order

Enables Topological Ordering

In tension with Bidirectional Collaboration

Conflicts with Circular Dependency

Contracts Checklist Creation Kernel

Tensions Directed Acyclic Graph (DAG) / Bidirectional Collaboration

Violated by Circular Dependency

Detected by cycle detection

Measured by cycle count

Refactored by Invert Dependency, Extract Interface, Split Module

Enforced by graph checks

Before

graph.addEdge("foo", "bar");
graph.addEdge("bar", "foo");

After

const dag = new Dag();
dag.addEdge("foo", "bar");
if (dag.wouldCreateCycle("bar", "foo")) throw new Error("cycle rejected");

How it is checked

Checked by graph checks

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Layering, Build Order, Topological Ordering

Shape it refuses Circular Dependency

Vector Clocks

Details

Definition A mechanism that keeps one counter per node on each update, so two updates can be compared as ordered or concurrent.

Requires Node Identity, Version Vector

Reinforces Causal Consistency

Enables Concurrent Update Detection

In tension with Metadata Size

Conflicts with Single Global Clock Assumption

Tensions Vector Clocks / Metadata Size

Violated by Lost Update

Detected by lost causality in distributed updates

Measured by conflict detection accuracy

Refactored by none

Enforced by replication protocol tests

Before

const winner = a.updatedAt > b.updatedAt ? a : b;

After

const relation = compareVectorClocks(a.clock, b.clock);
if (relation === "concurrent") return mergeFoo(a, b);
return relation === "after" ? a : b;

How it is checked

Checked by replication protocol tests

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Node Identity, Version Vector, Causal Consistency, Concurrent Update Detection

Shape it refuses Single Global Clock Assumption

Lamport Clocks

Details

Definition A mechanism that stamps each event with a logical counter, advanced on every send and receive, to give a partial order.

Requires Logical Counter

Reinforces Happens-Before Reasoning

Enables Partial Ordering

In tension with No Concurrent Causality Distinction

Conflicts with Wall-Clock Ordering Assumption

Tensions Lamport Clocks / No Concurrent Causality Distinction

Distinct from Logical Counter: Lamport clocks are the whole stamping scheme, advanced on every send and receive, while the logical counter is the value each process keeps.

Violated by Wall-Clock Ordering Assumption

Detected by timestamp ordering anomalies

Measured by ordering anomaly rate

Refactored by none

Enforced by protocol tests

Before

const event = { at: Date.now(), value: foo };

After

const event = { logicalTime: lamport.tick(), value: foo };
lamport.observe(remoteEvent.logicalTime);

How it is checked

Checked by protocol tests

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Logical Counter, Happens-Before Reasoning, Partial Ordering

Shape it refuses Wall-Clock Ordering Assumption

Hybrid Logical Clocks

Details

Definition A mechanism that combines physical time with a logical counter, so timestamps follow causal order and stay close to wall-clock time.

Requires Happens-Before Relationship

Reinforces Causal Consistency, Event Ordering

Enables Wall-Clock-Correlated Causal Order

In tension with Clock Skew

Conflicts with Physical-Clock-Only Ordering

Tensions Hybrid Logical Clocks / Clock Skew

Violated by Physical-Clock-Only Ordering

Detected by last-writer-wins on physical time

Measured by out-of-causal-order event rate

Refactored by none

Enforced by distributed-systems review

Before

const event = { at: Date.now(), value: foo };

After

const event = { hlc: hlc.now(), value: foo };
hlc.update(remoteEvent.hlc);

How it is checked

Checked by distributed-systems review

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Happens-Before Relationship, Causal Consistency, Event Ordering, Wall-Clock-Correlated Causal Order

Shape it refuses Physical-Clock-Only Ordering

CRDTs

Details

Definition A mechanism that stores replicated state in data types whose merge is commutative, so replicas converge without coordination.

Requires Commutative Merge

Reinforces Eventual Consistency, Causal Consistency

Enables Conflict-Free Replica Convergence

In tension with Metadata Overhead, Last-Write-Wins Overwrite

Conflicts with none

Tensions CRDTs / Metadata Overhead, CRDTs / Last-Write-Wins Overwrite

Violated by Lost Update

Detected by lost updates under concurrent replication

Measured by merge-conflict data-loss rate

Refactored by none

Enforced by replication design review

Before

foo.tags = incoming.updatedAt > foo.updatedAt ? incoming.tags : foo.tags;

After

foo.tags = orSet.merge(foo.tags, incoming.tags);

How it is checked

Checked by replication design review

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Commutative Merge, Eventual Consistency, Causal Consistency, Conflict-Free Replica Convergence

Shape it refuses Not answered

Total-Order Broadcast

Details

Definition A mechanism that delivers every message to every node in the same order, agreed by consensus.

Requires Consensus

Reinforces Event Ordering, Consistency

Enables Identical Delivery Order Across Nodes

In tension with Latency

Conflicts with Per-Node Independent Ordering

Tensions Total-Order Broadcast / Latency

Violated by Per-Node Independent Ordering

Detected by state divergence across nodes given same events

Measured by cross-node order divergence rate

Refactored by none

Enforced by distributed-systems review

Before

replica.apply(event);

After

const sequenced = await totalOrder.broadcast(event);
replica.applyInOrder(sequenced.sequence, sequenced.event);

How it is checked

Checked by distributed-systems review

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Consensus, Event Ordering, Consistency, Identical Delivery Order Across Nodes

Shape it refuses Per-Node Independent Ordering

CAP Theorem

Details

Definition A conceptual representation of the choice a distributed store makes during a network partition, between consistency and availability.

Requires Network Partition Possibility

Reinforces Causal Consistency, Eventual Consistency

Enables Explicit Consistency/Availability Choice Under Partition

In tension with Latency

Conflicts with Assumed Total Consistency And Availability

Referenced by PACELC Theorem

Tensions CAP Theorem / Latency

Distinct from Causal Consistency: The CAP theorem states the trade-off a store makes during a partition, while causal consistency is one guarantee a store can offer.

Distinct from Eventual Consistency: The CAP theorem is the trade-off, while eventual consistency is the guarantee an available store settles for.

Distinct from PACELC Theorem: The CAP theorem covers only a partition, while PACELC adds the latency and consistency trade-off of a healthy network.

Violated by Assumed Total Consistency And Availability

Detected by split-brain writes or stalls during network partitions

Measured by consistency/availability violations during partition events

Refactored by none

Enforced by distributed-systems review

Before

await Promise.all(replicas.map((r) => r.write(foo)));
return "always consistent and available";

After

const policy = partitionPolicyFor(foo.class);
return policy === "CP" ? writeWithQuorum(foo) : writeAvailableAndReconcile(foo);

How it is checked

Checked by distributed-systems review

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on Network Partition Possibility, Causal Consistency, Eventual Consistency, Explicit Consistency/Availability Choice Under Partition

Shape it refuses Assumed Total Consistency And Availability

PACELC Theorem

Details

Definition A conceptual representation that extends the CAP theorem with the trade-off a healthy network still forces, between latency and consistency.

Requires CAP Theorem

Reinforces CAP Theorem, Latency

Enables Latency-Consistency Trade-off When Healthy

In tension with Throughput

Conflicts with Consistency Assumed Free When Healthy

Tensions PACELC Theorem / Throughput

Violated by Consistency Assumed Free When Healthy

Detected by tail latency driven by synchronous cross-region consistency during normal operation

Measured by latency-vs-staleness tradeoff per read class

Refactored by none

Enforced by distributed-systems review

Before

const foo = await readFromAllRegionsStrongly(id);

After

const foo = tolerateStaleness(id.class)
  ? await readLocalReplica(id)
  : await readStronglyAcrossRegions(id);

How it is checked

Checked by distributed-systems review

Population Every event, replica update and dependency edge whose order affects the result

Freshness A verdict stands until the event schema, the ordering key or the replication protocol changes

Refusal The ordering or consistency test fails, or the graph check rejects the edge that breaks the order

Observation Causation metadata on events, ordering-anomaly counts from tests, and the extracted dependency graph

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 ordering key and the replication protocol, which every event and replica update conforms to

Depends on CAP Theorem, CAP Theorem, Latency, Latency-Consistency Trade-off When Healthy

Shape it refuses Consistency Assumed Free When Healthy

Contracts / Interfaces / Compatibility

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.

flowchart LR
    n_design_by_contract["Design by Contract"]
    n_explicit_contracts["Explicit Contracts"]
    n_stable_interfaces["Stable Interfaces"]
    n_interface_based_design["Interface-Based Design"]
    n_contract_first_design["Contract-First Design"]
    n_api_contract["API Contract"]
    n_service_contract["Service Contract"]
    n_data_contract["Data Contract"]
    n_schema_contract["Schema Contract"]
    n_semantic_contracts["Semantic Contracts"]
    n_preconditions["Preconditions"]
    n_postconditions["Postconditions"]
    n_invariant["Invariant"]
    n_backward_compatibility["Backward Compatibility"]
    n_forward_compatibility["Forward Compatibility"]
    n_versioning["Versioning"]
    n_protocol_compatibility["Protocol Compatibility"]
    n_interoperability["Interoperability"]
    n_uniform_interface["Uniform Interface"]
    n_consumer_driven_contracts["Consumer-Driven Contracts"]
    n_design_by_contract --> n_preconditions
    n_design_by_contract --> n_postconditions
    n_design_by_contract --> n_invariant
    n_explicit_contracts --> n_stable_interfaces
    n_explicit_contracts --> n_interoperability
    n_explicit_contracts --> n_contract_first_design
    n_stable_interfaces --> n_versioning
    n_stable_interfaces --> n_backward_compatibility
    n_interface_based_design --> n_stable_interfaces
    n_contract_first_design --> n_explicit_contracts
    n_contract_first_design --> n_schema_contract
    n_contract_first_design --> n_interoperability
    n_contract_first_design --> n_backward_compatibility
    n_api_contract --> n_versioning
    n_api_contract --> n_stable_interfaces
    n_api_contract --> n_interoperability
    n_service_contract --> n_api_contract
    n_data_contract --> n_interoperability
    n_schema_contract --> n_data_contract
    n_preconditions --> n_design_by_contract
    n_postconditions --> n_invariant
    n_backward_compatibility --> n_versioning
    n_backward_compatibility --> n_stable_interfaces
    n_versioning --> n_stable_interfaces
    n_versioning --> n_backward_compatibility
    n_protocol_compatibility --> n_versioning
    n_protocol_compatibility --> n_interoperability
    n_consumer_driven_contracts --> n_explicit_contracts
    n_consumer_driven_contracts --> n_backward_compatibility
    n_consumer_driven_contracts --> n_contract_first_design
Loading

Design by Contract

Details

Definition A design rule that every operation states the preconditions it needs, the postconditions it guarantees and the invariants it keeps.

Requires Preconditions, Postconditions, Invariant

Reinforces Correctness, Predictability

Enables Contract Testing, Liskov Substitution Principle (LSP)

In tension with Development Speed

Conflicts with Implicit Behavior

Referenced by Preconditions, Correctness

Contracts Architectural Contract Algebra, Contract-Based Verification Kernel

Tensions Design by Contract / Development Speed

Distinct from Liskov Substitution Principle (LSP): Design by contract states each operation's conditions, while Liskov substitution requires a subtype to keep the conditions of its base type.

Violated by Implicit Assumptions, Trusting Invalid Inputs

Detected by missing assertions, missing validation, vague public APIs

Measured by contract coverage

Refactored by Precondition Check, Postcondition Check, Invariant Check

Enforced by assertions, contract tests, static analysis

Refused by rules design-by-contract

Before

function divideFoo(total: number, count: number) {
  return total / count;
}

After

function divideFoo(total: number, count: number): number {
  if (!Number.isFinite(total)) throw new Error("pre: total must be finite");
  if (!Number.isInteger(count) || count <= 0)
    throw new Error("pre: count must be positive");
  const result = total / count;
  if (!Number.isFinite(result)) throw new Error("post: result must be finite");
  return result;
}

How it is checked

Checked by assertions, contract tests, static analysis

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Preconditions, Postconditions, Invariant, Correctness, Predictability, Contract Testing, Liskov Substitution Principle (LSP)

Shape it refuses Implicit Behavior

Explicit Contracts

Details

Definition A design rule that every boundary declares the shape and meaning of what crosses it in a typed contract.

Requires Stable Interfaces, Type Safety

Reinforces Predictability, Interoperability

Enables Contract-First Design

In tension with Rapid Prototyping

Conflicts with Implicit Contract

Referenced by Contract-First Design, Consumer-Driven Contracts, Predictability, Autonomy

Contracts Contracts Core, PAG Authoring Kernel

Tensions Explicit Contracts / Rapid Prototyping

Distinct from Determinism: Explicit contracts declare what crosses a boundary, while determinism makes the same inputs give the same result.

Distinct from Contract-First Design: Explicit contracts require a declared contract, while contract-first design fixes when it is written, before the implementation.

Distinct from Independence: Explicit contracts declare boundaries, while independence lets a module be tested and deployed without its neighbors.

Violated by Dynamic Untyped Boundaries, Untyped Payloads

Detected by public methods without DTO/schema, dynamic maps at boundaries

Measured by boundary contract coverage

Refactored by Introduce Boundary DTO, Schema Validation, Extract Interface

Enforced by schema validation, API linting

Before

function saveFoo(foo: any): any {
  return fooStore.save(foo);
}

After

interface SaveFoo {
  execute(
    input: Readonly<{ id: FooId; name: string }>,
  ): Promise<{ saved: true; version: number }>;
}
const saveFoo: SaveFoo = { execute: (input) => fooStore.save(input) };

How it is checked

Checked by schema validation, API linting

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Stable Interfaces, Type Safety, Predictability, Interoperability, Contract-First Design

Shape it refuses Implicit Contract, Implicit Contract

Stable Interfaces

Details

Definition The degree to which a public interface keeps its signatures and meaning across releases.

Requires Versioning, Backward Compatibility

Reinforces Low Coupling, Replaceability

Enables Independent Consumers

In tension with Evolution Speed

Conflicts with Breaking Change

Referenced by Explicit Boundaries, Runtime Extensibility, Explicit Contracts, Interface-Based Design, API Contract, Backward Compatibility, Versioning, Low Coupling, Encapsulation, Composability, Replaceability, Dependency Inversion Principle (DIP), Plugin Architecture, Extension Points, Principle of Least Surprise

Tensions Stable Interfaces / Evolution Speed

Violated by Unversioned Breaking Change, Schema Drift

Detected by incompatible API diffs

Measured by breaking-change frequency

Refactored by Versioning, Extract Adapter, Gradual Deprecation

Enforced by API diff checks, contract tests

Before

class FooService {
  createFoo(name: string, tags: string[], notify: boolean, source: string) {}
}

After

type CreateFooRequest = Readonly<{
  name: string;
  tags: readonly string[];
  extensions: Readonly<Record<string, unknown>>;
}>;
interface FooService {
  create(request: CreateFooRequest): Promise<FooId>;
}

How it is checked

Checked by API diff checks, contract tests

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Versioning, Backward Compatibility, Low Coupling, Replaceability, Independent Consumers

Shape it refuses Breaking Change

Interface-Based Design

Details

Definition A design rule that a module depends on interfaces, and the implementation behind each one is supplied from outside.

Requires Abstraction, Stable Interfaces

Reinforces Dependency Inversion Principle (DIP), Testability

Enables Dependency Injection, Adapter Pattern

In tension with Interface Overuse

Conflicts with Concrete Coupling

Referenced by Composition Over Inheritance

Tensions Interface-Based Design / Interface Overuse

Distinct from Composition Over Inheritance: Interface-based design depends on interfaces, while composition over inheritance reuses behavior by holding objects rather than extending classes.

Distinct from Dependency Inversion Principle (DIP): Interface-based design depends on interfaces supplied from outside, while dependency inversion also fixes that the policy side owns the interface.

Violated by Concrete Coupling

Detected by concrete constructor dependencies

Measured by interface-to-implementation boundary ratio

Refactored by Extract Interface, Dependency Injection

Enforced by dependency rules

Before

function processFoo(store: SqlFooStore, foo: Foo) {
  return store.insert(foo);
}

After

interface FooWriter {
  save(foo: Foo): Promise<void>;
}
function processFoo(store: FooWriter, foo: Foo) {
  return store.save(foo);
}

How it is checked

Checked by dependency rules

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Abstraction, Stable Interfaces, Dependency Inversion Principle (DIP), Testability, Dependency Injection, Adapter Pattern

Shape it refuses Concrete Coupling

Contract-First Design

Details

Definition A design rule that a boundary's contract is written and agreed before the implementation behind it.

Requires Explicit Contracts, Schema Contract

Reinforces Interoperability, Backward Compatibility

Enables Consumer-Driven Development

In tension with Iteration Speed

Conflicts with Implementation-First Integration

Referenced by Explicit Contracts, Consumer-Driven Contracts

Tensions Contract-First Design / Iteration Speed

Violated by Implementation-First Integration

Detected by absent contract before implementation

Measured by contract-first coverage

Refactored by Define Contract, Code Generation, Contract Testing

Enforced by CI contract gates

Before

app.post("/foo", async (request) => fooStore.save(await request.json()));

After

type CreateFooRequest = { name: string };
type CreateFooResponse = { id: FooId; version: 1 };
interface CreateFooContract {
  request: CreateFooRequest;
  response: CreateFooResponse;
}
app.post("/foo", implement<CreateFooContract>(createFoo));

How it is checked

Checked by CI contract gates

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Explicit Contracts, Schema Contract, Interoperability, Backward Compatibility, Consumer-Driven Development

Shape it refuses Implementation-First Integration

API Contract

Details

Definition A rule or precondition that each endpoint declares its request, response and error shapes in a versioned schema.

Requires Schema, Versioning, Stable Interfaces

Reinforces Interoperability, Predictability

Enables Client Compatibility

In tension with Evolution

Conflicts with Breaking API Change

Referenced by Service Contract, Self-Describing API

Tensions API Contract / Evolution

Distinct from Semantic Contract: An API contract declares the shapes of requests, responses and errors, while a semantic contract declares what the operations mean.

Violated by Ad-Hoc Endpoints, Inconsistent Error Model

Detected by OpenAPI drift, missing endpoint schemas

Measured by contract coverage, breaking diff count

Refactored by Define Contract, Standard Error Contract, Versioning

Enforced by OpenAPI linting, contract tests

Before

app.get("/foo/:id", async (request) => fooStore.find(request.params.id));

After

const getFooApi = endpoint({
  method: "GET",
  path: "/v1/foo/{id}",
  request: FooIdSchema,
  response: FooResponseSchema,
  errors: ["FOO_NOT_FOUND"] as const,
});

How it is checked

Checked by OpenAPI linting, contract tests

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Schema, Versioning, Stable Interfaces, Interoperability, Predictability, Client Compatibility

Shape it refuses Breaking API Change

Service Contract

Details

Definition A rule or precondition that a service declares its operations, their results and their side effects to every consumer.

Requires API Contract, Semantic Contract

Reinforces Autonomy, Compatibility

Enables Independent Deployment

In tension with Distributed Evolution

Conflicts with Hidden Service Coupling

Referenced by Service-Oriented Architecture

Tensions Service Contract / Distributed Evolution

Distinct from API Contract: A service contract declares a service's operations, results and side effects, while an API contract declares the shapes at each endpoint.

Distinct from Semantic Contract: A service contract covers one service's whole surface, while a semantic contract is the meaning part of any interface's contract.

Violated by Hidden Service Coupling, Silent Breaking Changes

Detected by consumer failures after service changes

Measured by consumer contract pass rate

Refactored by Consumer-Driven Contract Tests, Service Level Objectives, Versioning

Enforced by contract tests, deployment gates

Before

class FooClient {
  create(body: any) {
    return http.post("/foo", body);
  }
}

After

interface FooServiceContract {
  create(input: CreateFoo): Promise<Result<FooCreated, FooError>>;
}
class FooClient implements FooServiceContract {
  create(input: CreateFoo) {
    return transport.call("Foo.Create", input);
  }
}

How it is checked

Checked by contract tests, deployment gates

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on API Contract, Semantic Contract, Autonomy, Compatibility, Independent Deployment

Shape it refuses Hidden Service Coupling

Data Contract

Details

Definition A rule or precondition that data exchanged between parties has declared fields, types, nullability and meaning.

Requires Schema, Type Safety, Semantic Consistency

Reinforces Interoperability, Data Quality

Enables Schema Evolution

In tension with Flexible Ingestion

Conflicts with Schema Drift

Referenced by Schema Contract, Schema Validation, Canonical Data Model

Tensions Data Contract / Flexible Ingestion

Violated by Untyped Payloads, Null Semantics Drift

Detected by data validation failures, schema mismatch

Measured by schema conformance rate

Refactored by Introduce Boundary DTO, Schema Validation, Canonical Data Model

Enforced by schema registry, validation gates

Before

type FooMessage = Record<string, unknown>;
queue.publish("foo", payload);

After

type FooMessageV1 = Readonly<{
  type: "FooCreated";
  version: 1;
  fooId: FooId;
  name: string;
}>;
queue.publish<FooMessageV1>("foo.created.v1", message);

How it is checked

Checked by schema registry, validation gates

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Schema, Type Safety, Semantic Consistency, Interoperability, Data Quality, Schema Evolution

Shape it refuses Schema Drift

Schema Contract

Details

Definition A rule or precondition that every payload is validated against a machine-readable schema at the boundary it crosses.

Requires Canonical Schema, Schema Validation

Reinforces Data Contract, Compatibility

Enables Automated Validation

In tension with Schema Flexibility

Conflicts with Ad-Hoc Payloads

Referenced by Contract-First Design, Schema Validation, Canonical Schema

Tensions Schema Contract / Schema Flexibility

Distinct from Data Contract: A data contract declares the fields, types and meaning of exchanged data, while a schema contract validates each payload against a schema at the boundary.

Violated by Ad-Hoc Payloads, Schema Drift

Detected by schema diff failures

Measured by schema validation coverage

Refactored by Schema Validation, Binary Schema Encoding, Define Contract

Enforced by schema registry, CI schema checks

Before

const foo = JSON.parse(raw) as Foo;

After

const FooSchema = object({ id: string(), count: integer() });
const foo: Foo = FooSchema.parse(JSON.parse(raw));

How it is checked

Checked by schema registry, CI schema checks

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Canonical Schema, Schema Validation, Data Contract, Compatibility, Automated Validation

Shape it refuses Ad-Hoc Payloads

Semantic Contracts

Details

Definition A rule or precondition that each term and value at a boundary has one agreed meaning, beyond its type.

Requires Ubiquitous Language, Domain Model

Reinforces Semantic Consistency, Correctness

Enables Reliable Integration

In tension with Cross-Domain Translation

Conflicts with Ambiguous Naming

Referenced by Domain Model, Semantic Consistency, Ubiquitous Language

Tensions Semantic Contracts / Cross-Domain Translation

Violated by Ambiguous Naming

Detected by conflicting field meanings, overloaded names

Measured by semantic conflict count

Refactored by Name the Concept, Split Bounded Context, Anti-Corruption Layer

Enforced by domain glossary, contract review

Before

function reserveFoo(count: number) {
  return fooStore.decrement(count);
}

After

type PositiveCount = number & { readonly __brand: "PositiveCount" };
function reserveFoo(count: PositiveCount): Promise<{ reserved: true }> {
  return fooInventory.reserveExactly(count);
}

How it is checked

Checked by domain glossary, contract review

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Ubiquitous Language, Domain Model, Semantic Consistency, Correctness, Reliable Integration

Shape it refuses Ambiguous Naming

Preconditions

Details

Definition A rule or precondition that must hold on an operation's input and state before the operation runs.

Requires Input Validation

Reinforces Design by Contract, Fail Fast

Enables Correctness

In tension with Permissive APIs

Conflicts with Implicit Assumptions

Referenced by Design by Contract, Liskov Substitution Principle (LSP), Fail Fast

Tensions Preconditions / Permissive APIs

Distinct from Invariant: A precondition holds before one operation runs, while an invariant holds in every reachable state.

Distinct from Postconditions: A precondition is checked before an operation runs, while a postcondition is guaranteed when it returns.

Violated by Trusting Invalid Inputs

Detected by missing validation before state transition

Measured by invalid-input handling coverage

Refactored by Precondition Check, Schema Validation

Enforced by validation rules, static analysis

Before

function renameFoo(foo: Foo, name: string) {
  foo.name = name;
}

After

function renameFoo(foo: Foo, name: string) {
  if (foo.status !== "active") throw new Error("pre: Foo must be active");
  if (name.trim().length === 0) throw new Error("pre: name required");
  foo.rename(name.trim());
}

How it is checked

Checked by validation rules, static analysis

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Input Validation, Design by Contract, Fail Fast, Correctness

Shape it refuses Implicit Assumptions

Postconditions

Details

Definition A rule or precondition that an operation's result and resulting state must satisfy when it returns.

Requires Result Validation, Invariant

Reinforces Correctness, Predictability

Enables Testability

In tension with Runtime Cost

Conflicts with Undefined Results

Referenced by Design by Contract, Liskov Substitution Principle (LSP)

Tensions Postconditions / Runtime Cost

Distinct from Invariant: A postcondition holds when one operation returns, while an invariant holds in every state an entity can reach.

Violated by Undefined Results

Detected by missing assertions on results

Measured by property test coverage

Refactored by Invariant Check, Introduce Typed Result, Contract Testing

Enforced by property tests, invariant checks

Before

async function createFoo(foo: Foo) {
  return fooStore.save(foo);
}

After

async function createFoo(foo: Foo): Promise<FooId> {
  await fooStore.save(foo);
  const saved = await fooStore.find(foo.id);
  if (!saved) throw new Error("post: Foo must be persisted");
  return saved.id;
}

How it is checked

Checked by property tests, invariant checks

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Result Validation, Invariant, Correctness, Predictability, Testability

Shape it refuses Undefined Results

Invariant

Details

Definition A rule or precondition that holds for an entity or aggregate in every state it can reach.

Requires Encapsulation, Validation

Reinforces Correctness, Consistency

Enables Safe Refactoring

In tension with Flexibility

Conflicts with External State Mutation

Referenced by Domain Model, Aggregate, Design by Contract, Postconditions, Liskov Substitution Principle (LSP), Consistency

Tensions Invariant / Flexibility

Violated by Reachable Invalid State

Detected by mutable public state, missing invariant checks

Measured by invariant test coverage

Refactored by Encapsulate State, Factory Pattern, Validate at the Boundary

Enforced by domain tests, constructors, type system

Before

class FooAccount {
  balance = 0;
  withdraw(amount: number) {
    this.balance -= amount;
  }
}

After

class FooAccount {
  #balance = 0;
  withdraw(amount: number) {
    if (amount <= 0 || amount > this.#balance)
      throw new Error("invariant: balance >= 0");
    this.#balance -= amount;
  }
}

How it is checked

Checked by domain tests, constructors, type system

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Encapsulation, Validation, Correctness, Consistency, Safe Refactoring

Shape it refuses External State Mutation

Backward Compatibility

Details

Definition A rule or precondition that a new version keeps working for consumers written against an older one.

Requires Versioning, Stable Interfaces

Reinforces Consumer Safety

Enables Incremental Deployment

In tension with Cleanup / Simplification

Conflicts with Breaking Change

Referenced by Stable Interfaces, Contract-First Design, Versioning, Consumer-Driven Contracts, Declared Jurisdiction

Tensions Backward Compatibility / Cleanup / Simplification

Distinct from Consumer-Driven Contracts: Backward compatibility is the property a new version keeps, while consumer-driven contracts are how a provider verifies it against recorded expectations.

Violated by Breaking Change

Detected by API/schema diff

Measured by breaking-change count

Refactored by Versioning, Gradual Deprecation, Extract Adapter

Enforced by compatibility tests, API diff gates

Before

app.get("/foo", () => ({ label: "Foo", tags: [] }));

After

app.get("/v1/foo", () => ({ name: "Foo" }));
app.get("/v2/foo", () => ({ label: "Foo", tags: [] }));

How it is checked

Checked by compatibility tests, API diff gates

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Versioning, Stable Interfaces, Consumer Safety, Incremental Deployment

Shape it refuses Breaking Change

Forward Compatibility

Details

Definition A rule or precondition that an older reader accepts data from a newer writer by ignoring the fields it does not know rather than failing on them.

Requires Extensible Schema

Reinforces Evolutionary Architecture

Enables Rolling Upgrades

In tension with Strong Validation

Conflicts with Strict Fragile Parsers

Tensions Forward Compatibility / Strong Validation

Distinct from Extensible Schema: Forward compatibility is the reader tolerating unknown fields, while an extensible schema is the writer's shape that lets fields be added.

Violated by Strict Fragile Parsers

Detected by parser failures on additive changes

Measured by forward-compatibility test pass rate

Refactored by Extension Points, Tolerant Reader

Enforced by compatibility test matrix

Refused by rules forward-compatibility

Before

function readFoo(input: { name: string }) {
  if (Object.keys(input).length !== 1) throw new Error("unknown field");
  return input.name;
}

After

type FooEnvelope = { name: string; extensions?: Record<string, unknown> };
function readFoo(input: FooEnvelope) {
  return { name: input.name, extensions: input.extensions ?? {} };
}

How it is checked

Checked by compatibility test matrix

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Extensible Schema, Evolutionary Architecture, Rolling Upgrades

Shape it refuses Strict Fragile Parsers

Versioning

Details

Definition A mechanism that labels each release of an interface or schema, so consumers can tell compatible changes from breaking ones.

Requires Stable Interfaces, Compatibility Policy

Reinforces Backward Compatibility, Governance

Enables Controlled Evolution

In tension with Version Sprawl

Conflicts with Silent Breaking Changes

Referenced by Stable Interfaces, API Contract, Backward Compatibility, Protocol Compatibility, Integration Events

Contracts Versioned Evolution Over Breaking Change, Living Profile Kernel

Tensions Versioning / Version Sprawl

Violated by Unversioned Breaking Change

Detected by incompatible diff without version bump

Measured by version compliance, deprecation window

Refactored by none

Enforced by release gates, API checks

Before

queue.publish("foo.created", { id: foo.id, name: foo.name });

After

queue.publish("foo.created.v2", {
  schemaVersion: 2,
  id: foo.id,
  label: foo.name,
});

How it is checked

Checked by release gates, API checks

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Stable Interfaces, Compatibility Policy, Backward Compatibility, Governance, Controlled Evolution

Shape it refuses Silent Breaking Changes

Protocol Compatibility

Details

Definition A rule or precondition that both ends of a connection speak a declared protocol version they both support.

Requires Protocol Contract, Versioning

Reinforces Interoperability

Enables Multi-Client Integration

In tension with Protocol Optimization

Conflicts with Proprietary Drift

Tensions Protocol Compatibility / Protocol Optimization

Distinct from Protocol Contract: Protocol compatibility is both ends agreeing on a supported version, while the protocol contract is the set of messages and sequences that version defines.

Violated by Proprietary Drift

Detected by protocol conformance failure

Measured by conformance test pass rate

Refactored by Extract Adapter, Standardize the Interface

Enforced by conformance tests

Before

socket.send(JSON.stringify({ action: "save", foo }));

After

type FooFrameV1 = { protocol: "foo/1"; type: "save"; payload: Foo };
socket.send(
  encodeFrame<FooFrameV1>({ protocol: "foo/1", type: "save", payload: foo }),
);

How it is checked

Checked by conformance tests

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Protocol Contract, Versioning, Interoperability, Multi-Client Integration

Shape it refuses Proprietary Drift

Interoperability

Details

Definition The degree to which separate systems exchange data and use it correctly through shared formats and contracts.

Requires Contracts, Standards, Compatibility

Reinforces Portability, Integration

Enables Cross-System Communication

In tension with Domain-Specific Optimization

Conflicts with Proprietary Coupling

Referenced by Explicit Contracts, Contract-First Design, API Contract, Data Contract, Protocol Compatibility, Standards Compliance, Integration Events, Robustness Principle, Standardization, Self-Describing API, Adapter Pattern, Schema Validation, Canonical Data Model, Semantic Consistency

Tensions Interoperability / Domain-Specific Optimization

Distinct from Portability: Interoperability is systems exchanging data correctly, while portability is software running on another platform unchanged.

Distinct from Compatibility: Interoperability is exchange through shared formats and contracts, while compatibility is working across versions without modification.

Distinct from Data Quality: Interoperability is exchange between systems, while data quality is the accuracy and completeness of the data exchanged.

Distinct from Domain-Specific Optimization: Interoperability is broad exchange, while domain-specific optimization is the tuning for one domain it trades against.

Distinct from Integration: Interoperability is the ability to exchange data correctly, while integration is the degree systems are actually connected into one whole.

Distinct from Semantic Consistency: Interoperability spans separate systems, while semantic consistency is one name keeping one meaning inside a system.

Distinct from Discoverability: Interoperability is exchanging data correctly, while discoverability is how easily a component's capabilities are found.

Violated by Proprietary Coupling, Implicit Assumptions

Detected by integration test failures

Measured by interoperability test coverage

Refactored by Standardize the Interface, Extract Adapter, Schema Validation

Enforced by contract tests, standards checks

Before

fooClient.send(serializeWithPrivateFormat(foo));

After

const payload: JsonFooV1 = toJsonFooV1(foo);
fooClient.send(JSON.stringify(payload), { contentType: "application/json" });

How it is checked

Checked by contract tests, standards checks

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Contracts, Standards, Compatibility, Portability, Integration, Cross-System Communication

Shape it refuses Proprietary Coupling

Uniform Interface

Details

Definition A rule or precondition that every resource in an API uses the same verbs, response shapes and error format.

Requires Consistent Semantics, Stable Contracts

Reinforces Principle of Least Surprise

Enables API Usability

In tension with Specialized Endpoints

Conflicts with Ad-Hoc Endpoints, Chatty Interface

Referenced by Composite Pattern

Tensions Uniform Interface / Specialized Endpoints

Distinct from Consistent Semantics: A uniform interface fixes the same verbs, shapes and error format across resources, while consistent semantics fixes that an operation means the same thing everywhere.

Distinct from Stable Contracts: A uniform interface is sameness across resources, while stable contracts are sameness over time.

Violated by Ambiguous API, Inconsistent Error Model

Detected by API lint violations

Measured by endpoint consistency score

Refactored by Standardize the Interface, Standard Error Contract

Enforced by API style guide, OpenAPI linting

Before

fooApi.createFoo(foo);
barApi.post("/bar", bar);
bazApi.execute("DELETE_BAZ", baz.id);

After

resourceClient.post("/foos", foo);
resourceClient.post("/bars", bar);
resourceClient.delete(`/bazes/${baz.id}`);

How it is checked

Checked by API style guide, OpenAPI linting

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Consistent Semantics, Stable Contracts, Principle of Least Surprise, API Usability

Shape it refuses Ad-Hoc Endpoints, Chatty Interface

Consumer-Driven Contracts

Details

Definition A rule or precondition that a provider verifies each change against the expectations its consumers have recorded.

Requires Explicit Contracts

Reinforces Backward Compatibility, Contract-First Design

Enables Provider Change Safety, Consumer-Verified Compatibility

In tension with Provider Autonomy

Conflicts with Unversioned Breaking Change

Tensions Consumer-Driven Contracts / Provider Autonomy

Violated by Silent Breaking Changes

Detected by integration breaks discovered only in production

Measured by consumer-break incident rate

Refactored by Consumer-Driven Contract Tests

Enforced by contract test gate

Before

fooProvider.deploy(newFooApi);

After

const expectations = collectContractsFrom(["bar-service", "baz-service"]);
const result = verifyProvider(newFooApi, expectations);
if (!result.satisfied) throw new BrokenConsumerContractError(result.violations);
fooProvider.deploy(newFooApi);

How it is checked

Checked by contract test gate

Population Every public boundary: operations, endpoints, messages, schemas and protocol frames

Freshness A verdict stands for one version of the contract and goes stale when the contract or its implementation changes

Refusal The contract test, schema validation or API diff gate fails the change that breaks the contract

Observation The contract or schema compared with the implementation and with each consumer's recorded expectation

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 contract, which the implementation and each consumer's recorded expectation are compared against

Depends on Explicit Contracts, Backward Compatibility, Contract-First Design, Provider Change Safety, Consumer-Verified Compatibility

Shape it refuses Unversioned Breaking Change

Control / Coordination / Centralization

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.

flowchart LR
    n_control_plane["Control Plane"]
    n_orchestration["Orchestration"]
    n_centralized_configuration["Centralized Configuration"]
    n_centralized_authentication["Centralized Authentication"]
    n_centralized_logging["Centralized Logging"]
    n_decentralization["Decentralization"]
    n_leader_election["Leader Election"]
    n_consensus["Consensus"]
    n_choreography["Choreography"]
    n_control_plane --> n_orchestration
    n_orchestration --> n_control_plane
    n_leader_election --> n_consensus
    n_leader_election --> n_control_plane
    n_choreography --> n_decentralization
Loading

Control Plane

Details

Definition Descriptive data about the desired state of a distributed runtime, held in one place and applied to every node through a management interface.

Requires Management API, Policy

Reinforces Governance, Orchestration

Enables Centralized Control of Distributed Runtime

In tension with Availability

Conflicts with Fully Decentralized Control

Referenced by Orchestration, Leader Election

Contracts Control Plane

Tensions Control Plane / Availability

Violated by Scattered Configuration

Detected by manual node/service control

Measured by control coverage, control-plane availability

Refactored by Management API, Policy as Code

Enforced by platform architecture

Before

for (const node of fooNodes) {
  node.configure({ retries: 3, timeoutMs: 500 });
}

After

controlPlane.apply("foo-service", {
  retries: 3,
  timeoutMs: 500,
  rollout: "progressive",
});

How it is checked

Checked by platform architecture

Population Every node, service and workflow step that shares configuration, identity, logs, leadership or agreement

Freshness A verdict stands until membership, topology or the coordinating policy changes

Refusal The workflow test or the platform policy rejects a participant that bypasses the coordinator or the agreed value

Observation The control plane's recorded state compared with each participant's reported state

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 control plane's recorded state, which each participant's reported state is compared against

Depends on Management API, Policy, Governance, Orchestration, Centralized Control of Distributed Runtime

Shape it refuses Fully Decentralized Control

Orchestration

Details

Definition A mechanism that runs a multi-step workflow from one coordinator, which calls each step in order and tracks its outcome.

Requires Coordinator

Reinforces Control Plane, Saga Pattern

Enables Ordered Multi-Step Execution

In tension with Centralized Coordinator Coupling

Conflicts with Pure Choreography

Referenced by Control Plane

Contracts Workflow Creation Kernel

Tensions Orchestration / Centralized Coordinator Coupling

Distinct from Coordinator: Orchestration is the mechanism of driving a workflow from one place, while the coordinator is the component that plays that role.

Violated by Pure Choreography

Detected by unclear workflow ownership

Measured by workflow observability/completion

Refactored by none

Enforced by workflow tests

Before

await fooService.create(foo);
await barService.create(bar);
await bazService.create(baz);

After

await orchestrator.run("CreateFooFlow", {
  steps: [
    step("foo", () => fooService.create(foo)),
    step("bar", () => barService.create(bar)),
    step("baz", () => bazService.create(baz)),
  ],
});

How it is checked

Checked by workflow tests

Population Every node, service and workflow step that shares configuration, identity, logs, leadership or agreement

Freshness A verdict stands until membership, topology or the coordinating policy changes

Refusal The workflow test or the platform policy rejects a participant that bypasses the coordinator or the agreed value

Observation The control plane's recorded state compared with each participant's reported state

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 control plane's recorded state, which each participant's reported state is compared against

Depends on Coordinator, Control Plane, Saga Pattern, Ordered Multi-Step Execution

Shape it refuses Pure Choreography

Centralized Configuration

Details

Definition A design pattern that keeps every service's configuration in one versioned store the services read from.

Requires Config Store, Access Control

Reinforces Governance, Consistency

Enables Unified Config Management

In tension with Central Dependency Risk

Conflicts with Scattered Configuration

Tensions Centralized Configuration / Central Dependency Risk

Violated by Scattered Configuration

Detected by config drift

Measured by config drift count

Refactored by Schema Validation

Enforced by config policy

Before

const fooConfig = loadLocalFooConfig();
const barConfig = loadLocalBarConfig();
const bazConfig = loadLocalBazConfig();

After

const config = await configService.readVersioned("platform/v3");
fooApp.apply(config.foo);
barApp.apply(config.bar);
bazApp.apply(config.baz);

How it is checked

Checked by config policy

Population Every node, service and workflow step that shares configuration, identity, logs, leadership or agreement

Freshness A verdict stands until membership, topology or the coordinating policy changes

Refusal The workflow test or the platform policy rejects a participant that bypasses the coordinator or the agreed value

Observation The control plane's recorded state compared with each participant's reported state

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 control plane's recorded state, which each participant's reported state is compared against

Depends on Config Store, Access Control, Governance, Consistency, Unified Config Management

Shape it refuses Scattered Configuration

Centralized Authentication

Details

Definition A design pattern that verifies identity once, at a shared identity provider, and passes the result to each service.

Requires Identity Provider

Reinforces Security, Governance

Enables Unified Identity

In tension with Identity Provider Availability

Conflicts with Scattered Auth Implementations

Tensions Centralized Authentication / Identity Provider Availability

Violated by Scattered Auth Implementations

Detected by duplicated credential stores

Measured by auth centralization coverage

Refactored by Identity Provider

Enforced by security policy

Before

fooService.verifyToken(token);
barService.verifyToken(token);
bazService.verifyToken(token);

After

const identity = await identityProvider.authenticate(token);
await fooService.handle({ identity });
await barService.handle({ identity });
await bazService.handle({ identity });

How it is checked

Checked by security policy

Population Every node, service and workflow step that shares configuration, identity, logs, leadership or agreement

Freshness A verdict stands until membership, topology or the coordinating policy changes

Refusal The workflow test or the platform policy rejects a participant that bypasses the coordinator or the agreed value

Observation The control plane's recorded state compared with each participant's reported state

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 control plane's recorded state, which each participant's reported state is compared against

Depends on Identity Provider, Security, Governance, Unified Identity

Shape it refuses Scattered Auth Implementations

Centralized Logging

Details

Definition A design pattern that ships structured logs from every instance to one aggregated store.

Requires Log Aggregation

Reinforces Observability, Auditability

Enables Cross-Service Analysis

In tension with Cost/Personal Data Exposure

Conflicts with Local-Only Logs

Tensions Centralized Logging / Cost/Personal Data Exposure

Violated by Local-Only Logs

Detected by missing log shipping

Measured by log ingestion coverage

Refactored by Log Aggregation, Canonical Data Model

Enforced by observability policy

Before

fooService.writeLocalLog(event);
barService.writeLocalLog(event);
bazService.writeLocalLog(event);

After

const sink = new CentralLogSink();
fooService.useLogger(structuredLogger(sink));
barService.useLogger(structuredLogger(sink));
bazService.useLogger(structuredLogger(sink));

How it is checked

Checked by observability policy

Population Every node, service and workflow step that shares configuration, identity, logs, leadership or agreement

Freshness A verdict stands until membership, topology or the coordinating policy changes

Refusal The workflow test or the platform policy rejects a participant that bypasses the coordinator or the agreed value

Observation The control plane's recorded state compared with each participant's reported state

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 control plane's recorded state, which each participant's reported state is compared against

Depends on Log Aggregation, Observability, Auditability, Cross-Service Analysis

Shape it refuses Local-Only Logs

Decentralization

Details

Definition A design rule that decisions and runtime control sit with the teams and services that own them, joined by contracts.

Requires Autonomy, Contracts

Reinforces Microservices, Resilience

Enables Independent Ownership

In tension with Governance, Consistency

Conflicts with Centralized Control

Referenced by Choreography, Autonomy, Single Source of Truth

Tensions Decentralization / Governance, Decentralization / Consistency

Violated by Centralized Control

Detected by centralized team/service dependency

Measured by decision/deployment dependency count

Refactored by Assign Owner, Management API

Enforced by ownership model

Before

const coordinator = new GlobalFooCoordinator();
await coordinator.approveEveryFoo(foo);

After

await fooNode.validate(foo);
await fooNode.commit(foo);
await fooNode.publish({ type: "FooCommitted", fooId: foo.id });

How it is checked

Checked by ownership model

Population Every node, service and workflow step that shares configuration, identity, logs, leadership or agreement

Freshness A verdict stands until membership, topology or the coordinating policy changes

Refusal The workflow test or the platform policy rejects a participant that bypasses the coordinator or the agreed value

Observation The control plane's recorded state compared with each participant's reported state

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 control plane's recorded state, which each participant's reported state is compared against

Depends on Autonomy, Contracts, Microservices, Resilience, Independent Ownership

Shape it refuses Centralized Control

Leader Election

Details

Definition A mechanism that lets a group of nodes agree on one coordinator and replace it when it fails.

Requires Consensus

Reinforces Control Plane, Fault Tolerance

Enables Single-Writer Coordination, Automatic Failover of Leadership

In tension with Availability

Conflicts with Split-Brain Coordination

Tensions Leader Election / Availability

Violated by Split-Brain Coordination

Detected by concurrent leader actions / split-brain

Measured by split-brain incident rate

Refactored by none

Enforced by distributed-systems review

Before

if (process.env.IS_LEADER === "true") runFooScheduler();

After

const lease = await fooCoordinator.acquireLeadership("foo-scheduler", {
  ttlMs: 10_000,
});
lease.onAcquired(() => runFooScheduler());
lease.onLost(() => stopFooScheduler());

How it is checked

Checked by distributed-systems review

Population Every node, service and workflow step that shares configuration, identity, logs, leadership or agreement

Freshness A verdict stands until membership, topology or the coordinating policy changes

Refusal The workflow test or the platform policy rejects a participant that bypasses the coordinator or the agreed value

Observation The control plane's recorded state compared with each participant's reported state

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 control plane's recorded state, which each participant's reported state is compared against

Depends on Consensus, Control Plane, Fault Tolerance, Single-Writer Coordination, Automatic Failover of Leadership

Shape it refuses Split-Brain Coordination

Consensus

Details

Definition A mechanism that lets a quorum of nodes commit one value, so every correct node ends up with the same value.

Requires Quorum

Reinforces Consistency, Fault Tolerance

Enables Agreed Single Value Across Nodes

In tension with Latency, Availability

Conflicts with Independent Node Decisions

Referenced by Total-Order Broadcast, Leader Election

Tensions Consensus / Latency, Consensus / Availability

Distinct from Leader Election: Consensus commits one value across a quorum, while leader election uses it to agree on one coordinator and replace it when it fails.

Distinct from Total-Order Broadcast: Consensus agrees on one value, while total-order broadcast agrees on the order of every message.

Violated by Independent Node Decisions

Detected by divergent committed state across replicas

Measured by agreement-violation rate

Refactored by none

Enforced by distributed-systems review

Before

fooNodeA.setValue(value);

After

const committed = await fooCluster.propose(value, {
  quorum: majority(fooNodes),
});
if (!committed.accepted) throw new NoQuorumError();

How it is checked

Checked by distributed-systems review

Population Every node, service and workflow step that shares configuration, identity, logs, leadership or agreement

Freshness A verdict stands until membership, topology or the coordinating policy changes

Refusal The workflow test or the platform policy rejects a participant that bypasses the coordinator or the agreed value

Observation The control plane's recorded state compared with each participant's reported state

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 control plane's recorded state, which each participant's reported state is compared against

Depends on Quorum, Consistency, Fault Tolerance, Agreed Single Value Across Nodes

Shape it refuses Independent Node Decisions

Choreography

Details

Definition A mechanism that coordinates a cross-service flow through events, with each service reacting to the previous one's event.

Requires Event-Driven Architecture

Reinforces Decentralization, Autonomy

Enables Central-Orchestrator-Free Coordination

In tension with Traceability

Conflicts with Central Orchestrator Bottleneck

Tensions Choreography / Traceability

Violated by Central Orchestrator Bottleneck

Detected by a central coordinator coupled to all participants

Measured by orchestrator fan-out coupling

Refactored by none

Enforced by architecture review

Before

await orchestrator.run("CreateFoo", [
  () => createFoo(foo),
  () => reserveBar(foo),
  () => notifyBaz(foo),
]);

After

fooEvents.on("FooCreated", (event) => barService.reserve(event.fooId));
barEvents.on("BarReserved", (event) => bazService.notify(event.fooId));

How it is checked

Checked by architecture review

Population Every node, service and workflow step that shares configuration, identity, logs, leadership or agreement

Freshness A verdict stands until membership, topology or the coordinating policy changes

Refusal The workflow test or the platform policy rejects a participant that bypasses the coordinator or the agreed value

Observation The control plane's recorded state compared with each participant's reported state

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 control plane's recorded state, which each participant's reported state is compared against

Depends on Event-Driven Architecture, Decentralization, Autonomy, Central-Orchestrator-Free Coordination

Shape it refuses Central Orchestrator Bottleneck

Correctness / Determinism / Verification

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.

flowchart LR
    n_determinism["Determinism"]
    n_predictability["Predictability"]
    n_referential_transparency["Referential Transparency"]
    n_pure_functions["Pure Functions"]
    n_immutability["Immutability"]
    n_reproducibility["Reproducibility"]
    n_repeatability["Repeatability"]
    n_correctness["Correctness"]
    n_formal_verification["Formal Verification"]
    n_specification_based_testing["Specification-Based Testing"]
    n_property_based_testing["Property-Based Testing"]
    n_static_analysis["Static Analysis"]
    n_testability["Testability"]
    n_validation["Validation"]
    n_verification["Verification"]
    n_determinism --> n_predictability
    n_determinism --> n_reproducibility
    n_predictability --> n_determinism
    n_referential_transparency --> n_pure_functions
    n_referential_transparency --> n_immutability
    n_referential_transparency --> n_determinism
    n_referential_transparency --> n_testability
    n_pure_functions --> n_testability
    n_pure_functions --> n_determinism
    n_pure_functions --> n_referential_transparency
    n_immutability --> n_predictability
    n_reproducibility --> n_determinism
    n_repeatability --> n_verification
    n_repeatability --> n_predictability
    n_correctness --> n_validation
    n_formal_verification --> n_correctness
    n_specification_based_testing --> n_correctness
    n_property_based_testing --> n_correctness
    n_testability --> n_pure_functions
    n_validation --> n_correctness
    n_verification --> n_correctness
Loading

Determinism

Details

Definition A design rule that the same inputs and state always produce the same result, with time and randomness passed in as inputs.

Requires Controlled State, Controlled State

Reinforces Predictability, Reproducibility

Enables Reliable Testing

In tension with Runtime Adaptivity

Conflicts with Hidden Time/Randomness/Global State

Referenced by Predictability, Referential Transparency, Pure Functions, Reproducibility, Artificial Intelligence Architecture, Agentic Architecture, Write Scope and Read Population, One-Sided Liveness, Declare-Before-Read Order, Derived Party Count, Externally Resolved Slot

Contracts Computation Core

Tensions Determinism / Runtime Adaptivity

Distinct from Referential Transparency: Determinism is the same inputs giving the same result, while referential transparency is being able to replace an expression by its value.

Violated by Hidden Time/Randomness/Global State

Detected by flaky tests, hidden random/time calls

Measured by flake rate, reproducibility score

Refactored by Inject Clock and Randomness, Encapsulate State

Enforced by deterministic test rules

Before

function makeFoo(name: string) {
  return { id: crypto.randomUUID(), name, createdAt: new Date() };
}

After

function makeFoo(name: string, id: FooId, createdAt: Date): Foo {
  return { id, name, createdAt };
}

How it is checked

Checked by deterministic test rules

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Controlled State, Controlled State, Predictability, Reproducibility, Reliable Testing

Shape it refuses Hidden Time/Randomness/Global State

Predictability

Details

Definition The degree to which a caller can foresee what an operation does from its interface and contract.

Requires Determinism, Explicit Contracts

Reinforces Principle of Least Surprise

Enables Safe Refactoring

In tension with Dynamic Runtime Behavior

Conflicts with Hidden Behavior

Referenced by Runtime Discovery, Dynamic Binding, Runtime Extensibility, Design by Contract, Explicit Contracts, API Contract, Postconditions, Determinism, Immutability, Repeatability, Pattern Consistency, Declarative Configuration, Convention over Configuration, Principle of Least Surprise, State Isolation, Controlled Side Effects

Tensions Predictability / Dynamic Runtime Behavior

Distinct from Correctness: Predictability is foreseeing behavior from the contract, while correctness is the behavior matching its specification.

Distinct from Pattern Consistency: Predictability is foreseeing one operation, while pattern consistency is one problem solved one way across the codebase.

Distinct from Interoperability: Predictability is a caller foreseeing behavior, while interoperability is systems exchanging data.

Distinct from Reproducibility: Predictability is foreseeing what an operation does, while reproducibility is a run giving the same output from pinned inputs on another machine.

Distinct from Testability: Predictability is foreseeing behavior, while testability is exercising code in isolation.

Distinct from Concurrency Correctness: Predictability is foreseeing behavior from a contract, while concurrency correctness is freedom from races when units run at once.

Distinct from Dynamic Runtime Behavior: Predictability is foreseeable behavior, while dynamic runtime behavior is the adaptivity that undermines it.

Distinct from Maintainability: Predictability is foreseeing behavior, while maintainability is the ease of changing it.

Distinct from Security: Predictability is foreseeable behavior, while security is protection from misuse.

Distinct from Startup Cost: Predictability is foreseeable behavior, while startup cost is the time discovery adds at initialization.

Distinct from Repeatability: Predictability is foreseeing an outcome from the contract, while repeatability is rerunning and observing the same outcome.

Distinct from Runtime Extensibility: Predictability is fixed, foreseeable behavior, while runtime extensibility is adding capability to a running system.

Distinct from Static Safety: Predictability is a caller foreseeing behavior, while static safety is the compiler catching classes of error before the code runs.

Distinct from Thread Safety: Predictability is foreseeing behavior from a contract, while thread safety is data surviving concurrent access uncorrupted.

Violated by Hidden Side Effect, Temporal Coupling

Detected by nondeterministic tests, ambiguous APIs

Measured by flake/misuse rate

Refactored by Declare Capability, Define Contract

Enforced by tests, contracts, linting

Before

function saveFoo(foo: Foo) {
  if (Math.random() > 0.5) return memoryStore.save(foo);
  return sqlStore.save(foo);
}

After

function saveFoo(store: FooStore, foo: Foo) {
  return store.save(foo);
}

How it is checked

Checked by tests, contracts, linting

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Determinism, Explicit Contracts, Principle of Least Surprise, Safe Refactoring

Shape it refuses Hidden Behavior

Referential Transparency

Details

Definition A design rule that an expression can be replaced by its value without changing the program's behavior.

Requires Pure Functions, Immutability

Reinforces Determinism, Testability

Enables Safe Substitution

In tension with Stateful IO

Conflicts with Side Effects

Referenced by Pure Functions

Tensions Referential Transparency / Stateful IO

Distinct from Immutability: Referential transparency lets an expression be replaced by its value, while immutability forbids a value from changing after creation.

Violated by Hidden Time/Randomness/Global State

Detected by hidden dependency on time/random/global state

Measured by pure function coverage

Refactored by Pure Functions, Dependency Injection

Enforced by code review, functional boundaries

Before

function fooTotal(values: number[]) {
  globalCounter += 1;
  return values.reduce((a, b) => a + b, 0) + globalCounter;
}

After

function fooTotal(values: readonly number[]) {
  return values.reduce((a, b) => a + b, 0);
}

How it is checked

Checked by code review, functional boundaries

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Pure Functions, Immutability, Determinism, Testability, Safe Substitution

Shape it refuses Side Effects

Pure Functions

Details

Definition A technique for writing logic as functions whose result depends only on their arguments and which have no side effects.

Requires No Side Effects, Explicit Inputs

Reinforces Testability, Determinism

Enables Referential Transparency

In tension with Stateful Operations

Conflicts with Hidden IO

Referenced by Referential Transparency, Testability

Tensions Pure Functions / Stateful Operations

Violated by Side Effects, Hidden IO

Detected by side-effect calls inside pure layer

Measured by pure core ratio

Refactored by Pure Core / Imperative Shell

Enforced by layer rules, tests

Before

function normalizeFoo(foo: Foo) {
  foo.name = foo.name.trim();
  fooStore.save(foo);
  return foo;
}

After

function normalizeFoo(foo: Foo): Foo {
  return { ...foo, name: foo.name.trim() };
}

How it is checked

Checked by layer rules, tests

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on No Side Effects, Explicit Inputs, Testability, Determinism, Referential Transparency

Shape it refuses Hidden IO

Immutability

Details

Definition A design rule that a value is never changed after it is created, and a change produces a new value.

Requires Value Semantics

Reinforces Thread Safety, Predictability

Enables Safe Sharing

In tension with Allocation Cost

Conflicts with Shared Mutable State

Referenced by Value Object, Referential Transparency, Independent Lifetime Axes

Tensions Immutability / Allocation Cost

Violated by Shared Mutable State, Exposed Internals

Detected by setters on value objects, mutable public fields

Measured by mutable state count

Refactored by Make Immutable

Enforced by type system, lint rules

Refused by rules immutability

Before

type Foo = { name: string; tags: string[] };
function addTag(foo: Foo, tag: string) {
  foo.tags.push(tag);
  return foo;
}

After

type Foo = Readonly<{ name: string; tags: readonly string[] }>;
function addTag(foo: Foo, tag: string): Foo {
  return { ...foo, tags: [...foo.tags, tag] };
}

How it is checked

Checked by type system, lint rules

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Value Semantics, Thread Safety, Predictability, Safe Sharing

Shape it refuses Shared Mutable State

Reproducibility

Details

Definition The degree to which a build, test or training run gives the same output from the same pinned inputs on another machine.

Requires Determinism, Versioned Inputs

Reinforces Auditability

Enables Debugging, Compliance

In tension with Continuous Updates

Conflicts with Floating Dependencies, Flaky Test Normalization

Referenced by Determinism, Environment Parity, Infrastructure as Code, Immutable Infrastructure, Machine Learning Architecture, Prompt Engineering, Benchmarking

Tensions Reproducibility / Continuous Updates

Distinct from Continuous Updates: Reproducibility pins every input, while continuous updates are the dependency changes that pinning holds back.

Violated by Floating Dependencies

Detected by build output drift

Measured by reproducible build/test pass rate

Refactored by Pin Versions

Enforced by lockfiles, build verification

Before

const result = trainFoo(data, { seed: Math.random() });

After

const config = {
  seed: 42,
  datasetVersion: "foo-v3",
  algorithmVersion: "1.2.0",
} as const;
const result = trainFoo(data, config);

How it is checked

Checked by lockfiles, build verification

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Determinism, Versioned Inputs, Auditability, Debugging, Compliance

Shape it refuses Floating Dependencies, Flaky Test Normalization

Repeatability

Details

Definition The degree to which rerunning the same test or process in the same environment gives the same result.

Requires Controlled State

Reinforces Verification, Predictability

Enables Reliable Automation

In tension with Real-World Variability

Conflicts with Environment-Sensitive Behavior

Tensions Repeatability / Real-World Variability

Distinct from Real-World Variability: Repeatability is the same result from a controlled rerun, while real-world variability is how far those controlled conditions differ from production.

Violated by Environment-Sensitive Behavior

Detected by flaky test results

Measured by rerun consistency

Refactored by Containerization, Fake at the Boundary

Enforced by CI rerun policy

Before

test("foo", () => expect(runFoo(Date.now())).toEqual(snapshot()));

After

test("foo", () => {
  const clock = new FixedClock("2026-01-01T00:00:00Z");
  expect(runFoo(clock)).toEqual(expectedFoo);
});

How it is checked

Checked by CI rerun policy

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Controlled State, Verification, Predictability, Reliable Automation

Shape it refuses Environment-Sensitive Behavior

Correctness

Details

Definition The degree to which the behavior of code matches its specification.

Requires Specification, Validation, Tests

Reinforces Design by Contract

Enables Safe Operation

In tension with Delivery Speed

Conflicts with Undefined Behavior

Referenced by Domain Model, Happens-Before Relationship, Design by Contract, Semantic Contracts, Preconditions, Postconditions, Invariant, Formal Verification, Specification-Based Testing, Property-Based Testing, Validation, Verification, Fail Fast, Error Handling, Design Review, First-Principles Design, Model Evaluation, Finite State Machine, Schema Validation, Type Safety, Single Source of Truth, Semantic Consistency, Input Validation, Atomicity, ACID, Consistency, Isolation, Concurrency Control

Tensions Correctness / Delivery Speed

Distinct from Interoperability: Correctness is code matching its specification, while interoperability is separate systems exchanging data correctly.

Distinct from Observability: Correctness is matching the specification, while observability is inferring behavior from the signals a system emits.

Distinct from Maintainability: Correctness is behaving as specified now, while maintainability is the ease of changing the behavior later.

Distinct from Robustness: Correctness is behaving as specified for valid input, while robustness is continuing to operate under invalid input and stress.

Distinct from Simplicity: Correctness is matching the specification, while simplicity is the absence of unneeded structure.

Distinct from Model Safety: Correctness is matching a specification, while model safety is preventing harmful model inputs, outputs and actions.

Distinct from Resilience: Correctness is right behavior, while resilience is containing failure and recovering from it.

Distinct from Semantic Consistency: Correctness is behavior matching the specification, while semantic consistency is one name keeping one meaning.

Distinct from Security: Correctness is matching the specification, while security is protecting data and behavior from misuse.

Violated by Undefined Behavior

Detected by failing tests, invariant violations

Measured by defect rate, spec coverage

Refactored by Unit Tests, Define Contract

Enforced by CI, formal/static checks

Before

function averageFoo(total: number, count: number) {
  return total / count;
}

After

function averageFoo(total: number, count: number) {
  if (!Number.isFinite(total)) throw new Error("invalid total");
  if (!Number.isInteger(count) || count <= 0) throw new Error("invalid count");
  return total / count;
}

How it is checked

Checked by CI, formal/static checks

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Specification, Validation, Tests, Design by Contract, Safe Operation

Shape it refuses Undefined Behavior

Formal Verification

Details

Definition The activity of proving, against a formal specification, that an algorithm or protocol keeps its invariants for every input.

Requires Formal Specification

Reinforces Correctness

Enables Mathematical Assurance

In tension with Cost/Complexity

Conflicts with Informal Validation Only

Tensions Formal Verification / Cost/Complexity

Violated by Informal Validation Only

Detected by missing formal model for critical invariant

Measured by proven property coverage

Refactored by Formal Model

Enforced by proof tooling

Before

function transferFoo(a: FooBalance, b: FooBalance, amount: number) {
  a.value -= amount;
  b.value += amount;
}

After

function transferFoo(state: FooState, amount: PositiveAmount): FooState {
  requires(state.from >= amount.value);
  const next = { from: state.from - amount.value, to: state.to + amount.value };
  ensures(next.from + next.to === state.from + state.to);
  return next;
}

How it is checked

Checked by proof tooling

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Formal Specification, Correctness, Mathematical Assurance

Shape it refuses Informal Validation Only

Specification-Based Testing

Details

Definition The activity of deriving tests from a specification's stated behavior, independently of how the code implements it.

Requires Specification

Reinforces Correctness, Contracts

Enables Behavior Validation

In tension with Spec Maintenance

Conflicts with Implementation-Only Testing, Mock Mirage

Contracts Test Coverage Kernel

Tensions Specification-Based Testing / Spec Maintenance

Violated by Implementation-Only Testing

Detected by lack of spec-derived tests

Measured by spec coverage

Refactored by none

Enforced by test gates

Before

test("saveFoo", async () => expect(await saveFoo(foo)).toBeTruthy());

After

describeContract("FooStore", (store) => {
  it("returns the saved Foo", async () => {
    await store.save(foo);
    expect(await store.find(foo.id)).toEqual(foo);
  });
});

How it is checked

Checked by test gates

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Specification, Correctness, Contracts, Behavior Validation

Shape it refuses Implementation-Only Testing, Mock Mirage

Property-Based Testing

Details

Definition The activity of checking that a stated property holds for many generated inputs, and shrinking each failure to a minimal counterexample.

Requires Properties/Invariants

Reinforces Correctness, Robustness

Enables Broad Input Exploration

In tension with Shrinking/Debug Complexity

Conflicts with Example-Only Testing

Tensions Property-Based Testing / Shrinking/Debug Complexity

Violated by Example-Only Testing

Detected by missing generative tests for critical properties

Measured by property coverage, counterexample count

Refactored by Code Generation

Enforced by property test suite

Before

test("normalizeFoo", () =>
  expect(normalizeFoo({ name: " Foo " }).name).toBe("Foo"));

After

property(string(), (name) => {
  const once = normalizeFoo({ name });
  const twice = normalizeFoo(once);
  expect(twice).toEqual(once);
});

How it is checked

Checked by property test suite

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Properties/Invariants, Correctness, Robustness, Broad Input Exploration

Shape it refuses Example-Only Testing

Static Analysis

Details

Definition A mechanism that checks source code against a ruleset without running it.

Requires Ruleset

Reinforces Type Safety, Security, Architecture Compliance

Enables Automated Enforcement

In tension with False Positives

Conflicts with Unchecked Dynamic Code

Referenced by Runtime Discovery, Metaprogramming, Reflection, Plugin Architecture, Type Safety

Tensions Static Analysis / False Positives

Distinct from Type Safety: Static analysis checks source against any ruleset, while type safety is the compiler rejecting operations on values of the wrong type.

Distinct from Automated Enforcement: Static analysis is one way to check source without running it, while automated enforcement is any machine check that rules hold.

Violated by Ignored Analyzer Findings

Detected by static analysis rule failures

Measured by issue count, false-positive rate

Refactored by Automated Enforcement, Track Rule Metrics

Enforced by CI quality gates

Before

const foo: any = loadFoo();
foo.nmae.toUpperCase();

After

const foo: Foo = loadFoo();
foo.name.toUpperCase();
runTypeCheck({ noImplicitAny: true, strictNullChecks: true });

How it is checked

Checked by CI quality gates

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Ruleset, Type Safety, Security, Architecture Compliance, Automated Enforcement

Shape it refuses Unchecked Dynamic Code

Testability

Details

Definition The degree to which code can be tested in isolation, with its dependencies, time and randomness supplied by the test.

Requires Low Coupling, Deterministic Behavior

Reinforces Dependency Inversion Principle (DIP), Pure Functions

Enables Regression Safety

In tension with Encapsulation Extremes

Conflicts with Hidden Dependency, Test Pyramid Inversion

Referenced by Interface-Based Design, Postconditions, Referential Transparency, Pure Functions, Single Responsibility Principle (SRP), High Cohesion, Singleton Pattern, Stateless Processing, Dependency Injection, Service Locator Pattern, Ports and Adapters Architecture, Clean Architecture, State Isolation, Controlled Side Effects

Tensions Testability / Encapsulation Extremes

Distinct from High Cohesion: Testability is running code in isolation, while high cohesion is its members sharing one purpose.

Distinct from Encapsulation Extremes: Testability is observing a unit in a test, while encapsulation extremes are the hiding that makes it hard to observe.

Distinct from Explicit Dependencies: Testability is supplying a unit's dependencies in a test, while explicit dependencies are those dependencies being visible in its signature.

Violated by Hidden Time/Randomness/Global State, Hidden Dependency

Detected by difficult setup, excessive mocking, flaky tests

Measured by test setup complexity, coverage, flake rate

Refactored by Dependency Injection, Make Effects Explicit

Enforced by test gates, architecture review

Before

function createFoo(name: string) {
  return fooDb.save({ id: crypto.randomUUID(), name, createdAt: new Date() });
}

After

function createFoo(name: string, ids: IdSource, clock: Clock, store: FooStore) {
  return store.save({ id: ids.nextFooId(), name, createdAt: clock.now() });
}

How it is checked

Checked by test gates, architecture review

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Low Coupling, Deterministic Behavior, Dependency Inversion Principle (DIP), Pure Functions, Regression Safety

Shape it refuses Hidden Dependency, Test Pyramid Inversion

Validation

Details

Definition The activity of checking that inputs and delivered behavior meet the acceptance criteria of their users.

Requires Acceptance Criteria

Reinforces Correctness

Enables Fitness for Use

In tension with Iteration Speed

Conflicts with Assumption-Driven Delivery

Referenced by Invariant, Correctness, Fail Fast, Self-Describing Structures, Metadata-Driven Design, Canonicalization, Consistency

Tensions Validation / Iteration Speed

Violated by Assumption-Driven Delivery

Detected by missing acceptance tests

Measured by acceptance coverage

Refactored by Validate at the Boundary, Component Tests

Enforced by CI gates, QA policy

Before

function createFoo(input: any) {
  return fooStore.save(input);
}

After

function createFoo(input: unknown) {
  const foo = CreateFooSchema.parse(input);
  return fooStore.save(foo);
}

How it is checked

Checked by CI gates, QA policy

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Acceptance Criteria, Correctness, Fitness for Use

Shape it refuses Assumption-Driven Delivery

Verification

Details

Definition The activity of checking that an implementation conforms to its specification.

Requires Specification

Reinforces Correctness

Enables Specification Compliance

In tension with Cost

Conflicts with Untested Implementation

Referenced by Repeatability

Contracts Codebase Verification Kernel

Tensions Verification / Cost

Violated by Untested Implementation

Detected by missing tests/static checks

Measured by verification coverage

Refactored by Unit Tests, Static Analysis

Enforced by CI gates

Before

await fooStore.save(foo);
return { ok: true };

After

await fooStore.save(foo);
const persisted = await fooStore.find(foo.id);
if (!persisted || persisted.version !== foo.version)
  throw new Error("verification failed");
return { ok: true } as const;

How it is checked

Checked by CI gates

Population Every function, build and test run whose result the verification claims to hold

Freshness A verdict stands for the code, inputs and dependency versions it ran against, and goes stale when any of them changes

Refusal The failing test, proof or analyzer finding fails the gate

Observation Test, proof and analyzer results, plus reruns that show whether a result repeats

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 specification the test or proof encodes, which a result is compared against

Depends on Specification, Correctness, Specification Compliance

Shape it refuses Untested Implementation

Portability / Infrastructure / Deployment

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.

flowchart LR
    n_portability["Portability"]
    n_platform_independence["Platform Independence"]
    n_environment_parity["Environment Parity"]
    n_containerization["Containerization"]
    n_infrastructure_as_code["Infrastructure as Code"]
    n_standards_compliance["Standards Compliance"]
    n_protocol_independence["Protocol Independence"]
    n_configuration_externalization["Configuration Externalization"]
    n_immutable_infrastructure["Immutable Infrastructure"]
    n_platform_independence --> n_portability
    n_environment_parity --> n_configuration_externalization
    n_environment_parity --> n_infrastructure_as_code
    n_containerization --> n_portability
    n_containerization --> n_environment_parity
    n_protocol_independence --> n_portability
    n_configuration_externalization --> n_portability
    n_configuration_externalization --> n_environment_parity
    n_immutable_infrastructure --> n_infrastructure_as_code
    n_immutable_infrastructure --> n_environment_parity
Loading

Portability

Details

Definition The degree to which software runs on another platform or environment without code changes.

Requires Abstraction, Standards

Reinforces Replaceability

Enables Platform Migration

In tension with Platform Optimization

Conflicts with Platform-Specific Coupling

Referenced by Interoperability, Platform Independence, Containerization, Protocol Independence, Configuration Externalization, Low Coupling, Abstraction, Independence, Case Dialect

Tensions Portability / Platform Optimization

Distinct from Integration: Portability is running on another platform, while integration is being connected to other systems.

Distinct from Platform Optimization: Portability is running anywhere unchanged, while platform optimization is the tuning for one platform that it gives up.

Violated by Platform-Specific Coupling

Detected by platform-specific imports in core

Measured by portability violation count

Refactored by Extract Adapter, Introduce Port

Enforced by dependency rules

Before

const path = "C:\\foo\\data\\foos.json";
const processId = windowsApi.currentProcessId();

After

const path = join(config.dataDirectory, "foos.json");
const processId = runtime.processId();

How it is checked

Checked by dependency rules

Population Every platform call, environment, configuration value and infrastructure resource the deployment uses

Freshness A verdict stands until the code, the image, the configuration or the live infrastructure changes

Refusal The import rule, config scan or drift detection fails the change or the deploy

Observation Platform imports read from source, and the declared infrastructure compared with the live state

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 declared infrastructure, which the live state is compared against

Depends on Abstraction, Standards, Replaceability, Platform Migration

Shape it refuses Platform-Specific Coupling

Platform Independence

Details

Definition A design rule that portable layers reach the operating system and vendor services only through abstractions.

Requires Platform Abstraction

Reinforces Portability

Enables Cross-Platform Deployment

In tension with Native Optimization

Conflicts with OS/Vendor Lock-In

Tensions Platform Independence / Native Optimization

Violated by OS/Vendor Lock-In

Detected by OS-specific paths/APIs in portable layers

Measured by cross-platform test pass rate

Refactored by Introduce Port, Canonicalization

Enforced by cross-platform CI

Before

function saveFoo(foo: Foo) {
  return winRegistry.write("Foo", foo);
}

After

interface FooPersistence {
  save(foo: Foo): Promise<void>;
}
function saveFoo(foo: Foo, persistence: FooPersistence) {
  return persistence.save(foo);
}

How it is checked

Checked by cross-platform CI

Population Every platform call, environment, configuration value and infrastructure resource the deployment uses

Freshness A verdict stands until the code, the image, the configuration or the live infrastructure changes

Refusal The import rule, config scan or drift detection fails the change or the deploy

Observation Platform imports read from source, and the declared infrastructure compared with the live state

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 declared infrastructure, which the live state is compared against

Depends on Platform Abstraction, Portability, Cross-Platform Deployment

Shape it refuses OS/Vendor Lock-In

Environment Parity

Details

Definition A design rule that development, test, staging and production run the same build, differing only in configuration.

Requires Configuration Externalization, Infrastructure as Code

Reinforces Reproducibility

Enables Reliable Deployment

In tension with Cost

Conflicts with Snowflake Environments

Referenced by Containerization, Configuration Externalization, Immutable Infrastructure

Tensions Environment Parity / Cost

Distinct from Configuration Externalization: Environment parity runs the same build everywhere, while configuration externalization is how the differences are kept outside that build.

Violated by Snowflake Environments

Detected by works-in-dev-only defects

Measured by environment drift

Refactored by Containerization, Externalize Configuration, Infrastructure as Code

Enforced by environment drift checks

Before

if (env === "dev") useMemoryFooStore();
if (env === "prod") useSqlFooStore();

After

const container = buildFooImage("foo-app:1.0.0");
runEnvironment("dev", container, devConfig);
runEnvironment("prod", container, prodConfig);

How it is checked

Checked by environment drift checks

Population Every platform call, environment, configuration value and infrastructure resource the deployment uses

Freshness A verdict stands until the code, the image, the configuration or the live infrastructure changes

Refusal The import rule, config scan or drift detection fails the change or the deploy

Observation Platform imports read from source, and the declared infrastructure compared with the live state

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 declared infrastructure, which the live state is compared against

Depends on Configuration Externalization, Infrastructure as Code, Reproducibility, Reliable Deployment

Shape it refuses Snowflake Environments

Containerization

Details

Definition A mechanism that packages an application with its runtime dependencies into an image that runs the same on any host.

Requires Image Definition, Externalized Config

Reinforces Portability, Environment Parity

Enables Repeatable Runtime Packaging

In tension with Image Complexity

Conflicts with Host-Coupled Deployment

Tensions Containerization / Image Complexity

Violated by Host-Coupled Deployment

Detected by manual host setup requirements

Measured by image reproducibility

Refactored by Externalize Configuration

Enforced by image scans, build pipeline

Before

installFooDependenciesOnHost();
startFooWithHostRuntime();

After

const image = containerImage({
  base: "node:22-alpine",
  copy: ["dist", "package.json"],
  command: ["node", "dist/main.js"],
});

How it is checked

Checked by image scans, build pipeline

Population Every platform call, environment, configuration value and infrastructure resource the deployment uses

Freshness A verdict stands until the code, the image, the configuration or the live infrastructure changes

Refusal The import rule, config scan or drift detection fails the change or the deploy

Observation Platform imports read from source, and the declared infrastructure compared with the live state

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 declared infrastructure, which the live state is compared against

Depends on Image Definition, Externalized Config, Portability, Environment Parity, Repeatable Runtime Packaging

Shape it refuses Host-Coupled Deployment

Infrastructure as Code

Details

Definition The practice of declaring infrastructure in versioned files and provisioning it from them.

Requires Declarative Configuration, Version Control

Reinforces Reproducibility, Governance

Enables Automated Provisioning

In tension with Tooling Complexity

Conflicts with Manual Infrastructure Changes

Referenced by Environment Parity, Immutable Infrastructure, Declarative Configuration

Tensions Infrastructure as Code / Tooling Complexity

Violated by Manual Infrastructure Changes

Detected by drift between code and live infra

Measured by drift count, IaC coverage

Refactored by none

Enforced by policy-as-code, drift detection

Before

cloudConsole.createDatabase("foo-prod");
cloudConsole.openPort(5432);

After

const fooDatabase = databaseResource({
  name: "foo-prod",
  engine: "postgres",
  encrypted: true,
  networkPolicy: "foo-only",
});

How it is checked

Checked by policy-as-code, drift detection

Population Every platform call, environment, configuration value and infrastructure resource the deployment uses

Freshness A verdict stands until the code, the image, the configuration or the live infrastructure changes

Refusal The import rule, config scan or drift detection fails the change or the deploy

Observation Platform imports read from source, and the declared infrastructure compared with the live state

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 declared infrastructure, which the live state is compared against

Depends on Declarative Configuration, Version Control, Reproducibility, Governance, Automated Provisioning

Shape it refuses Manual Infrastructure Changes

Standards Compliance

Details

Definition A rule or precondition that an implementation conforms to the published standard for its protocol, format or domain.

Requires Applicable Standard

Reinforces Interoperability, Compliance

Enables Certification/Compatibility

In tension with Innovation/Flexibility

Conflicts with Proprietary Deviation

Tensions Standards Compliance / Innovation/Flexibility

Distinct from Compliance: Standards compliance is technical conformance to a published protocol or format, while compliance is implementing and evidencing the controls a regulation requires.

Distinct from Applicable Standard: Standards compliance is conforming, while the applicable standard is the one standard identified to conform to.

Violated by Proprietary Deviation

Detected by conformance test failure

Measured by standard compliance score

Refactored by Contract Testing

Enforced by standards checks

Before

const payload = encodePrivateFooBinary(foo);

After

const payload: JsonFooV1 = toJsonFoo(foo);
http.send(JSON.stringify(payload), {
  contentType: "application/json; charset=utf-8",
});

How it is checked

Checked by standards checks

Population Every platform call, environment, configuration value and infrastructure resource the deployment uses

Freshness A verdict stands until the code, the image, the configuration or the live infrastructure changes

Refusal The import rule, config scan or drift detection fails the change or the deploy

Observation Platform imports read from source, and the declared infrastructure compared with the live state

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 declared infrastructure, which the live state is compared against

Depends on Applicable Standard, Interoperability, Compliance, Certification/Compatibility

Shape it refuses Proprietary Deviation

Protocol Independence

Details

Definition A design rule that domain logic is written against ports, and each transport protocol reaches it through its own adapter.

Requires Adapter/Port Abstraction

Reinforces Portability, Replaceability

Enables Protocol Swap

In tension with Protocol-Specific Features

Conflicts with Protocol-Coupled Domain Logic

Tensions Protocol Independence / Protocol-Specific Features

Violated by Protocol-Coupled Domain Logic

Detected by protocol imports in core layer

Measured by protocol leakage count

Refactored by Introduce Port, Extract Adapter

Enforced by import rules

Before

class FooService {
  handleHttp(request: HttpRequest) {
    return fooStore.save(request.body);
  }
}

After

class CreateFoo {
  constructor(private readonly store: FooStore) {}
  execute(input: CreateFooInput) {
    return this.store.save(Foo.create(input));
  }
}
httpAdapter.bind(createFoo);
grpcAdapter.bind(createFoo);

How it is checked

Checked by import rules

Population Every platform call, environment, configuration value and infrastructure resource the deployment uses

Freshness A verdict stands until the code, the image, the configuration or the live infrastructure changes

Refusal The import rule, config scan or drift detection fails the change or the deploy

Observation Platform imports read from source, and the declared infrastructure compared with the live state

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 declared infrastructure, which the live state is compared against

Depends on Adapter/Port Abstraction, Portability, Replaceability, Protocol Swap

Shape it refuses Protocol-Coupled Domain Logic

Configuration Externalization

Details

Definition A design rule that environment-specific values are read from validated external configuration at startup.

Requires Config Schema, Secure Config Handling

Reinforces Portability, Environment Parity

Enables Environment-Specific Deployment

In tension with Config Sprawl

Conflicts with Hardcoded Configuration

Referenced by Environment Parity

Tensions Configuration Externalization / Config Sprawl

Violated by Hardcoded Configuration

Detected by hardcoded URLs/secrets/paths

Measured by externalized config coverage

Refactored by Externalize Configuration, Validate at the Boundary

Enforced by secret/config scans

Before

const config = {
  fooUrl: "https://foo.prod.example",
  retries: 3,
};

After

type FooConfig = Readonly<{ fooUrl: URL; retries: number }>;
const config = FooConfigSchema.parse({
  fooUrl: process.env.FOO_URL,
  retries: process.env.FOO_RETRIES,
});

How it is checked

Checked by secret/config scans

Population Every platform call, environment, configuration value and infrastructure resource the deployment uses

Freshness A verdict stands until the code, the image, the configuration or the live infrastructure changes

Refusal The import rule, config scan or drift detection fails the change or the deploy

Observation Platform imports read from source, and the declared infrastructure compared with the live state

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 declared infrastructure, which the live state is compared against

Depends on Config Schema, Secure Config Handling, Portability, Environment Parity, Environment-Specific Deployment

Shape it refuses Hardcoded Configuration

Immutable Infrastructure

Details

Definition An approach in which servers are replaced from a new image for every change, instead of being patched in place.

Requires Infrastructure as Code

Reinforces Environment Parity, Reproducibility

Enables Deterministic Redeploys, Instance Replacement over Mutation

In tension with Deploy Time

Conflicts with In-Place Server Mutation

Tensions Immutable Infrastructure / Deploy Time

Violated by In-Place Server Mutation

Detected by SSH mutation of live instances

Measured by config drift across instances

Refactored by none

Enforced by deployment review

Before

ssh(server, "apt-get update && systemctl restart foo");

After

const image = buildFooImage("foo:1.4.0");
replaceInstances("foo", image);

How it is checked

Checked by deployment review

Population Every platform call, environment, configuration value and infrastructure resource the deployment uses

Freshness A verdict stands until the code, the image, the configuration or the live infrastructure changes

Refusal The import rule, config scan or drift detection fails the change or the deploy

Observation Platform imports read from source, and the declared infrastructure compared with the live state

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 declared infrastructure, which the live state is compared against

Depends on Infrastructure as Code, Environment Parity, Reproducibility, Deterministic Redeploys, Instance Replacement over Mutation

Shape it refuses In-Place Server Mutation

Core Modular Design

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.

flowchart LR
    n_single_responsibility["Single Responsibility Principle (SRP)"]
    n_separation_of_concerns["Separation of Concerns"]
    n_duplicate_code["Do Not Rep
Loading

Clone this wiki locally