Repository navigation
21 Ontology.Principles
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 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.
476 of 476 shown
- Anti-patterns
- Domain Architecture
- Runtime Discovery / Dynamic Binding
- Causality / Ordering / Distributed Time
- Contracts / Interfaces / Compatibility
- Control / Coordination / Centralization
- Correctness / Determinism / Verification
- Portability / Infrastructure / Deployment
- Core Modular Design
- SOLID / Object-Oriented Design
- Event / Messaging / Asynchronous Architecture
- Error Handling / Resilience
- Architecture Review / Evolution / Governance Artifacts
- Metadata / Self-Description / Declarative Systems
- Metaprogramming / Language-Oriented Architecture
- Model Architecture
- Observability / Auditability / Traceability
- Behavioral Patterns
- Creational Patterns
- Structural Patterns
- Scalability / Performance / Optimization
- Streaming / Pipeline / Dataflow Processing
- Plugin / Extensibility / IoC
- Self-Healing / Recovery / Deployment Safety
- Schema / Canonical Data / Semantics
- Security / Privacy / Compliance / Governance
- Codebase / System Architecture Styles
- Coordination Surfaces
- Taxonomy / Classification / Naming
- Transactions / State / Concurrency
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"]
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, state_transaction
- Layer: Enforcement Core
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
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, semantic_consistency, domain_boundary, control_coordination
- Aliases: Blob Class, God Class
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity
- Aliases: Concrete Dependency
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility, security_governance, model_governance
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility, causality_ordering
- Aliases: Implicit Payloads
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: semantic_consistency, state_transaction
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, state_transaction
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, model_governance
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: correctness_verification, security_governance
- Aliases: Document-Only Policy
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: runtime_extensibility, metaprogramming_modeling
- Aliases: Opaque Runtime
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: architecture_evolution
- Aliases: Unknown/Unowned Risk
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility
- Aliases: Opaque System
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility, event_messaging, architecture_evolution
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, contract_compatibility, state_transaction
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, contract_compatibility
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, contract_compatibility
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: event_messaging
- Aliases: Train Wreck
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, correctness_verification, control_coordination
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: correctness_verification, domain_boundary
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: architecture_evolution
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: architecture_evolution
- Aliases: Flag Argument
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, contract_compatibility, correctness_verification, object_creation
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: domain_boundary
- Aliases: Magic Number
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: runtime_extensibility
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: architecture_evolution
- Aliases: Law of the Instrument
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility, correctness_verification
- Aliases: Cargo-Cult Pattern Use
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: architecture_evolution
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: architecture_evolution
- Aliases: Dead Code
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, contract_compatibility, correctness_verification, causality_ordering
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: event_messaging
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: event_messaging
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: state_transaction
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: model_governance
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: correctness_verification
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: semantic_consistency
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, contract_compatibility, semantic_consistency, model_governance, domain_boundary
- Aliases: Anemic Model
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: state_transaction, correctness_verification, domain_boundary, control_coordination
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: correctness_verification, security_governance, control_coordination
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: correctness_verification, domain_boundary, control_coordination
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, domain_boundary
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: domain_boundary
- Aliases: Infrastructure-Centric Design, Framework-Centric Core
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, model_governance, domain_boundary
- Aliases: Shared Model Coupling
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity
- Aliases: Cyclic Dependencies
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: architecture_evolution
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity
- Aliases: Blocking Synchronous Chains
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, contract_compatibility
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: architecture_evolution
- Aliases: N+1 Query
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: correctness_verification, security_governance
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: resilience_recovery
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: resilience_recovery
- Aliases: Infinite Wait
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: resilience_recovery
- Aliases: Unbounded Ingestion
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility, correctness_verification
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: state_transaction
- Aliases: Whole-File Write Race
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: event_messaging
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: security_governance, model_governance
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: security_governance, model_governance
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: modularity, security_governance
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: architecture_evolution
- Aliases: Unbounded Data Collection
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: observability_traceability
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: correctness_verification, resilience_recovery
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: resilience_recovery
- Aliases: Manual-Only Recovery, Manual Intervention Dependency
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: state_transaction
- Aliases: Big-Bang Deployment
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility, architecture_evolution
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: domain_boundary
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: model_governance, domain_boundary
- Aliases: Over-Architecture
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: security_governance, performance_scaling
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility, correctness_verification, observability_traceability
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: semantic_consistency, correctness_verification
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: contract_compatibility, model_governance
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: model_governance
- Layer: Enforcement Core
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
- Kind: anti-pattern
- Category: anti-patterns
- Severity: discouraged
- Scope: model_governance
- Layer: Enforcement Core
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
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
- Kind: style
- Category: Domain Architecture
- Severity: contextual
- Scope: domain, bounded context, system
- Aliases: DDD
- Layer: Domain Modeling
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
- Kind: artifact
- Category: Domain Architecture
- Severity: contextual
- Scope: domain, bounded context
- Layer: Domain Modeling
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
- Kind: constraint
- Category: Domain Architecture
- Severity: recommended
- Scope: domain, service, team
- Layer: Domain Modeling
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
- Kind: activity
- Category: Domain Architecture
- Severity: recommended
- Scope: bounded contexts, integration
- Layer: Domain Modeling
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
- Kind: pattern
- Category: Domain Architecture
- Severity: recommended
- Scope: integration, bounded context boundary
- Layer: Domain Modeling
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
- Kind: principle
- Category: Domain Architecture
- Severity: mandatory
- Scope: module, component, service, domain
- Layer: Domain Modeling
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
- Kind: pattern
- Category: Domain Architecture
- Severity: contextual
- Scope: domain, consistency boundary, bounded context
- Layer: Domain Modeling
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
- Kind: pattern
- Category: Domain Architecture
- Severity: recommended
- Scope: domain, modeling, immutability
- Layer: Domain Modeling
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
- Kind: pattern
- Category: Domain Architecture
- Severity: contextual
- Scope: domain, identity, lifecycle
- Layer: Domain Modeling
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
- Kind: pattern
- Category: Domain Architecture
- Severity: contextual
- Scope: domain, behavior, coordination
- Layer: Domain Modeling
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
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
- Kind: mechanism
- Category: Runtime Discovery / Dynamic Binding
- Severity: contextual
- Scope: runtime, plugin, module, service
- Aliases: Auto-Discovery, Registry/Discovery Mechanism
- Layer: Extensibility Core
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
- Kind: mechanism
- Category: Runtime Discovery / Dynamic Binding
- Severity: contextual
- Scope: service, network, runtime
- Layer: Extensibility Core
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
- Kind: mechanism
- Category: Runtime Discovery / Dynamic Binding
- Severity: contextual
- Scope: runtime, interface, plugin, module, service
- Aliases: Late Binding, Runtime Binding
- Layer: Extensibility Core
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
- Kind: mechanism
- Category: Runtime Discovery / Dynamic Binding
- Severity: recommended
- Scope: method, interface, runtime
- Layer: Extensibility Core
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
- Kind: quality-attribute
- Category: Runtime Discovery / Dynamic Binding
- Severity: contextual
- Scope: runtime, plugin, system
- Layer: Extensibility Core
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
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
- Kind: principle
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Scope: event, workflow, distributed state
- Layer: Causality Core
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
- Kind: model
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Scope: distributed data, events
- Layer: Causality Core
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
- Kind: model
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Scope: concurrency, distributed events
- Layer: Causality Core
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
- Kind: constraint
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Scope: stream, queue, consumer
- Layer: Causality Core
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
- Kind: model
- Category: Causality / Ordering / Distributed Time
- Severity: recommended
- Scope: event, workflow, module
- Layer: Causality Core
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
- Kind: artifact
- Category: Causality / Ordering / Distributed Time
- Severity: mandatory
- Scope: codebase, runtime, deployment
- Layer: Causality Core
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
- Kind: constraint
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Mandatory for: dependency architecture
- Scope: dependency graph, workflow, build
- Aliases: Directed Dependencies
- Layer: Causality Core
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
- Kind: mechanism
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Scope: distributed events, replication
- Layer: Causality Core
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
- Kind: mechanism
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Scope: distributed events
- Layer: Causality Core
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
- Kind: mechanism
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Mandatory for: distributed systems
- Scope: event, distributed state, time
- Layer: Causality Core
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
- Kind: mechanism
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Scope: distributed state, replication, convergence
- Aliases: Conflict-Free Replicated Data Types
- Layer: Causality Core
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
- Kind: mechanism
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Mandatory for: distributed systems
- Scope: event, distributed state, ordering
- Layer: Causality Core
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
- Kind: model
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Mandatory for: distributed systems
- Scope: distributed state, consistency, availability
- Layer: Causality Core
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
- Kind: model
- Category: Causality / Ordering / Distributed Time
- Severity: contextual
- Scope: distributed state, consistency, latency
- Layer: Causality Core
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
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
- Kind: principle
- Category: Contracts / Interfaces / Compatibility
- Severity: recommended
- Scope: API, function, class, service
- Aliases: DbC
- Layer: Contracts Core
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
- Kind: principle
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: API, service, data, protocol
- Layer: Contracts Core
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
- Kind: quality-attribute
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: API, module, service
- Layer: Contracts Core
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
- Kind: principle
- Category: Contracts / Interfaces / Compatibility
- Severity: recommended
- Scope: class, module, service
- Layer: Contracts Core
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
- Kind: principle
- Category: Contracts / Interfaces / Compatibility
- Severity: recommended
- Scope: API, service, integration
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: API, service boundary
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: service, integration
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: data, message, persistence, integration
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: data, API, message
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: domain, API, data
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: function, method, API
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: recommended
- Scope: function, method, transaction
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: entity, aggregate, module, system
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: API, schema, protocol
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: recommended
- Scope: API, schema, protocol
- Aliases: Unknown Field Handling
- Layer: Contracts Core
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
- Kind: mechanism
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: API, schema, package, service
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: integration, network, message
- Layer: Contracts Core
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
- Kind: quality-attribute
- Category: Contracts / Interfaces / Compatibility
- Severity: mandatory
- Scope: API, data, protocol, system
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: recommended
- Scope: API, resource boundary
- Layer: Contracts Core
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
- Kind: constraint
- Category: Contracts / Interfaces / Compatibility
- Severity: recommended
- Scope: API, service, integration
- Layer: Contracts Core
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
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
- Kind: artifact
- Category: Control / Coordination / Centralization
- Severity: contextual
- Scope: platform, infrastructure, distributed system
- Layer: Execution Core
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
- Kind: mechanism
- Category: Control / Coordination / Centralization
- Severity: contextual
- Scope: workflow, deployment, services
- Layer: Execution Core
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
- Kind: pattern
- Category: Control / Coordination / Centralization
- Severity: contextual
- Scope: service, platform, runtime
- Layer: Execution Core
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
- Kind: pattern
- Category: Control / Coordination / Centralization
- Severity: recommended
- Scope: identity, system
- Layer: Execution Core
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
- Kind: pattern
- Category: Control / Coordination / Centralization
- Severity: recommended
- Scope: services, platform
- Layer: Execution Core
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
- Kind: principle
- Category: Control / Coordination / Centralization
- Severity: contextual
- Scope: system, team, service
- Layer: Execution Core
Details
Definition A design rule that decisions and runtime control sit with the teams and services that own them, joined by 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
- Kind: mechanism
- Category: Control / Coordination / Centralization
- Severity: contextual
- Mandatory for: distributed systems
- Scope: distributed system, coordination, availability
- Layer: Execution Core
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
- Kind: mechanism
- Category: Control / Coordination / Centralization
- Severity: contextual
- Mandatory for: distributed systems
- Scope: distributed system, agreement, consistency
- Layer: Execution Core
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
- Kind: mechanism
- Category: Control / Coordination / Centralization
- Severity: contextual
- Scope: distributed system, coordination, event
- Layer: Execution Core
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
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
- Kind: principle
- Category: Correctness / Determinism / Verification
- Severity: recommended
- Scope: function, process, build, test
- Layer: Computation Core
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
- Kind: quality-attribute
- Category: Correctness / Determinism / Verification
- Severity: recommended
- Scope: API, module, runtime
- Layer: Computation Core
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
- Kind: principle
- Category: Correctness / Determinism / Verification
- Severity: contextual
- Scope: function, expression
- Layer: Computation Core
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
- Kind: technique
- Category: Correctness / Determinism / Verification
- Severity: recommended
- Scope: function, domain logic
- Layer: Computation Core
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
- Kind: principle
- Category: Correctness / Determinism / Verification
- Severity: recommended
- Scope: data, value object, concurrency
- Layer: Computation Core
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
- Kind: quality-attribute
- Category: Correctness / Determinism / Verification
- Severity: recommended
- Scope: build, test, deployment, ML
- Layer: Computation Core
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
- Kind: quality-attribute
- Category: Correctness / Determinism / Verification
- Severity: mandatory
- Scope: test, build, process
- Layer: Computation Core
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
- Kind: quality-attribute
- Category: Correctness / Determinism / Verification
- Severity: mandatory
- Scope: function, module, system
- Layer: Computation Core
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
- Kind: activity
- Category: Correctness / Determinism / Verification
- Severity: contextual
- Scope: algorithm, protocol, critical system
- Layer: Computation Core
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
- Kind: activity
- Category: Correctness / Determinism / Verification
- Severity: recommended
- Scope: function, API, module
- Layer: Computation Core
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
- Kind: activity
- Category: Correctness / Determinism / Verification
- Severity: recommended
- Scope: function, algorithm, parser, domain invariant
- Layer: Computation Core
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
- Kind: mechanism
- Category: Correctness / Determinism / Verification
- Severity: mandatory
- Scope: codebase, build
- Layer: Computation Core
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
- Kind: quality-attribute
- Category: Correctness / Determinism / Verification
- Severity: mandatory
- Scope: class, module, service
- Layer: Computation Core
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
- Kind: activity
- Category: Correctness / Determinism / Verification
- Severity: mandatory
- Scope: input, behavior, requirement
- Layer: Computation Core
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
- Kind: activity
- Category: Correctness / Determinism / Verification
- Severity: mandatory
- Scope: implementation, system
- Layer: Computation Core
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
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
- Kind: quality-attribute
- Category: Portability / Infrastructure / Deployment
- Severity: contextual
- Scope: application, infrastructure, runtime
- Layer: Resource Core
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
- Kind: principle
- Category: Portability / Infrastructure / Deployment
- Severity: contextual
- Scope: application, runtime
- Layer: Resource Core
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
- Kind: principle
- Category: Portability / Infrastructure / Deployment
- Severity: recommended
- Scope: dev, test, staging, production
- Layer: Resource Core
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
- Kind: mechanism
- Category: Portability / Infrastructure / Deployment
- Severity: contextual
- Scope: application, runtime, deployment
- Layer: Resource Core
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
- Kind: activity
- Category: Portability / Infrastructure / Deployment
- Severity: contextual
- Mandatory for: managed infrastructure
- Scope: infrastructure, deployment
- Aliases: IaC
- Layer: Resource Core
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
- Kind: constraint
- Category: Portability / Infrastructure / Deployment
- Severity: contextual
- Scope: protocol, security, data, infrastructure
- Layer: Resource Core
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
- Kind: principle
- Category: Portability / Infrastructure / Deployment
- Severity: recommended
- Scope: integration, service boundary
- Layer: Resource Core
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
- Kind: principle
- Category: Portability / Infrastructure / Deployment
- Severity: mandatory
- Scope: application, deployment, runtime
- Aliases: Externalized Configuration
- Layer: Resource Core
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
- Kind: approach
- Category: Portability / Infrastructure / Deployment
- Severity: contextual
- Mandatory for: managed infrastructure
- Scope: infrastructure, deployment, reproducibility
- Layer: Resource Core
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
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
© 2025 Jay Baleine - Disciplined Methodology · Bane's Lab documentation is covered by CC BY-SA 4.0
Navigation
Reading path PAG
Methodology
Architecture
Ontology
Anatomy
- Reading
- Bane's Lab Site
- GovLab Extension Host
- Bane's Lab Build Scripts
- Bane's Lab Content
- Coordination Surface
- Bane's Lab Deploy
- Bane's Lab Server
- Bane's Lab Social Share
- Codebase Testing
- GovLab Constants
- GovLab Context
- GovLab Docs
- GovLab Patterns
- GovLab Pipeline
- GovLab Quality
- GovLab Stats
- Argv Contract
- Canonical Write
- Code Parse
- Content Fingerprint
- GovLab Paths
- Project Scripts
- Secrets
- Configs
FAQ
Links