Software Design Reference Reference · Glossary

Reference document · canonical vocabulary

Glossary

The canonical language of this course. Every lesson uses these terms in these senses; when a term is used loosely elsewhere, the resolution chosen here wins. Each entry carries the lesson that teaches it, and an Avoid line naming the words that blur it.

All 158 terms, A–Z Abstraction· Adapter· Admission control· Adversarial prompt· Advice process· Aggregate· Amdahl's law· Anchoring· Anonymization· Anti-corruption layer· Architecture Decision Record· Architecture driver· Assumption map· At-least-once delivery· Authoritative source· Batch size· Behaviorally anchored rating· Blast radius· Blue/green deployment· Boundary· Bounded context· Branch by abstraction· Canary release· Capstone· CD3 — Cost of Delay Divided by Duration· Change amplification· Characterization test· Co-change· Cohesion· Compatibility window· Compensating action· Compensating control· Composition· Composition root· Config graveyard· Consistency boundary· Consumer-driven contract· Context map· Contract test· Control coupling· Conway's law· Core domain· Correlation id· Cost of delay· Cost of divergence· Coupling· Data minimization· Dead-letter queue· Decision rights· Decision-change simulation· Deep module· Dependency direction· Deployment pipeline· Detection time· Disagree and commit· Domain· Domain invariant· DRI — Directly Responsible Individual· DRY — Don't Repeat Yourself· Dual-write window· Effective configuration· Enabling point· Entity· Entry diagnostic· Event sourcing· Event-driven architecture· Eventual consistency· Evidence milestone· Evidence rule· Exit cost· Expand / contract· Expected failure (xfail)· Fail-fast· False DRY· Feature flag· Fitness function· Forecast range· Fragile base class problem· Global coupling· Golden master· Graceful degradation· Guardrail· Higher-order function· Holdback cohort· Idempotency key· Idempotent· Information hiding· Interaction mode· KISS — Keep It Simple· Last-write-wins· Law of Demeter· Liskov substitution principle· Little's law· Manual seam· Message bus· Middle man· Object-level authorization· Open vs closed enum· Operation contract· Optimistic locking· PACELC· Parameter object· Poison message· Port· Product outcome· Protocol· Published boundary· Quality-attribute scenario· Ratchet· Read model· Read-your-writes consistency· Reason to change· Reconciliation check· Reconciliation condition· Release train· Repayment trigger· Repository· Responsibility· Reversal rehearsal· Reversibility· Rollout gate· Rubric· Rule of three· Seam· Shared kernel· Shared state· Speculative generality· Spike· Sprout and wrap· SRP — Single Responsibility Principle· State machine· Story map· Strangler fig· Strategy pattern· STRIDE· Structural typing· Subdomain· Superseding ADR· Team API· Technical-debt ledger· Tell, Don't Ask· Threat model· Tolerant reader· Total cost of ownership· Trade-off· Train wreck· Transactional outbox· Trust boundary· Ubiquitous language· Unit of work· Upgrade tax· Use case· User story· Value object· Vertical slice· Walking skeleton· Work in progress· YAGNI — You Ain't Gonna Need It

Structure and complexity

The vocabulary for talking about shape: what makes code hard to change, and how you measure it.

Coupling

How much one module depends on the internals or behavior of another. Low coupling means a module can change without forcing changes in its neighbors.

Avoid: tight coupling, entanglement, "spaghetti"

Taught in: lesson 0001

Cohesion

How strongly the elements inside one module belong together — whether they serve one purpose. High cohesion means a module has one reason to exist.

Avoid: god class, grab-bag module, "utils" folder

Taught in: lesson 0001

SRP — Single Responsibility Principle

A module should have one reason to change. The reason, not the responsibility, is the unit of design.

Avoid: "does one thing" (too vague), "one method" (too literal)

Taught in: lessons 0002, 0006

Reason to change

The concrete force (a new requirement, a new technology, a new policy) that would make you edit a module. Design units of code around single reasons to change.

Avoid: "responsibility" (fuzzier), "feature" (too coarse)

Taught in: lesson 0006

Change amplification

The number of places you must edit to make one logical change. It is the most direct measurement of design debt.

Avoid: "shotgun surgery" (the smell it produces)

Taught in: lessons 0006, 0033

DRY — Don't Repeat Yourself

Every piece of knowledge should have a single, unambiguous representation in the system. DRY targets knowledge, not text: two identical lines can encode different knowledge.

Avoid: copy-paste, WET ("write everything twice")

Taught in: lessons 0002, 0028

False DRY

Deduplication of text that encodes two different pieces of knowledge. The two copies look identical today because the facts happen to coincide; merging them couples parties that will diverge, and the first divergence has to be bent into the shared shape.

Avoid: “removing duplication” (when the duplication was never knowledge)

Taught in: lessons 0002, 0028

Rule of three

Wait for the third occurrence before extracting an abstraction. At one occurrence there is no pattern; at two the shape is a guess; by three the variation is visible and the change-rent of the copies is real.

Avoid: “don't repeat yourself” read as “never type it twice”

Taught in: lessons 0002, 0028, 0030

KISS — Keep It Simple

Prefer the solution with the least complexity that meets the requirement. Simplicity is a design target, not a default.

Avoid: cleverness, over-engineering, speculative generality

Taught in: lesson 0002

YAGNI — You Ain't Gonna Need It

Do not build capability you have no current evidence of needing. Unused generality is paid for forever and used never.

Avoid: speculative features, "just in case" hooks

Taught in: lessons 0002, 0030

Speculative generality

Parameters, hooks and layers built for cases that do not exist. It is paid for on every read of the current code and used by nobody. The counter-test: does the generality make today's case simpler? (Ousterhout)

Avoid: “future-proofing”, “extensible by design”

Taught in: lesson 0030

Abstraction

A simplified interface that hides the complexity of what lies behind it. A good abstraction is deeper than the sum of its parts.

Avoid: leaky abstraction, façade without substance

Taught in: lessons 0028, 0030

Deep module

A module with a small, simple interface hiding substantial implementation. The opposite of a shallow module, which exposes most of its work through the interface. (Ousterhout)

Avoid: "thin layer" (a shallow module by another name)

Taught in: lessons 0001, 0034

Information hiding

Keeping design decisions that are likely to change inside a module, invisible to its users.

Avoid: encapsulation (usually used for the same idea, but includes runtime state protection)

Taught in: lessons 0019, 0034

Boundary

The edge of a module where one set of concerns hands off to another. Boundaries are where you enforce invariants, translate representations, and choose failure behavior.

Avoid: "layer" (a boundary is a seam, a layer is a convention)

Taught in: lessons 0014, 0022

Seam

A place where you can alter behavior without editing the code in question — a hook, an interface, a dependency-injection point. Seams make change and testing possible.

Avoid: "extension point" (a seam with a designed-for purpose)

Taught in: lessons 0005, 0035

Cost of divergence

The worst plausible outcome if two copies of a rule or value drift apart before anyone notices. It is the number that should decide whether “just extract it” is safe: low cost of divergence tolerates a deduplication mistake, high cost demands an explicit shared owner instead.

Avoid: “just DRY it up” (skips the question), duplication treated as always bad

Taught in: lesson 0028

Published boundary

An interface that others already depend on. Narrowing or changing it is no longer a local decision — every consumer pays for the change — so the bar for altering a published boundary is higher than for an internal one with no callers yet.

Avoid: “just tighten the interface” (ignores who already calls it), treating an internal refactor and a public one the same way

Taught in: lesson 0030

Amdahl's law

The speedup from optimizing one part of a system is capped by how much of the total runtime that part accounts for: if a component is only p of the runtime, no amount of work on it can improve the whole by more than p. It is the arithmetic that stops effort going to the wrong bottleneck.

Avoid: optimizing whatever is easiest to optimize, skipping the profiler in favor of instinct

Taught in: lesson 0034

Reversibility

How expensive a decision is to undo once made. Cheap-to-reverse decisions can be made fast on thin evidence; expensive-to-reverse ones earn the extra analysis YAGNI would otherwise forbid spending.

Avoid: “move fast” applied uniformly, treating every decision as equally risky

Taught in: lesson 0002

Co-change

How often two parts of the code appear together in the same commit. High co-change between parts that live in different modules is evidence they share a reason to change and belong on the same side of a boundary, whatever the folder structure says today.

Avoid: “change coupling” (the same idea; prefer this term for consistency), physical proximity mistaken for the signal

Taught in: lesson 0053

Objects and the domain

The words for the things the software is actually about, and the shapes that protect them.

Domain

The problem space the software exists to serve: the rules, entities, and workflows that are true regardless of technology.

Avoid: "business logic" (if you must, mean the same thing)

Taught in: lesson 0011

Subdomain

An area of the business identified by the work it performs — part of the problem space, with its own vocabulary and rules. Classifying subdomains as core, supporting, or generic says where the valuable complexity lives.

Avoid: "module", "service" (solution-space words), "business unit"

Taught in: lesson 0051

Core domain

The subdomain that differentiates the business — the part worth bespoke modeling and the most design attention, because off-the-shelf solutions cannot beat it. Everything else earns commodity treatment.

Avoid: "the main feature", "everything important"

Taught in: lesson 0051

Use case

A description of what a user or system needs to accomplish, told as an actor, a goal, and the sequence the system must support. It names the interactions and outcomes before any component exists. (Larman)

Avoid: "feature", a user story masquerading as a scenario

Taught in: lesson 0051

Operation contract

A specification of one system operation: its name, its actors, preconditions that must hold, and postconditions stating what changed — facts created, modified, or deleted. It makes rules precise without prescribing implementation. (Larman)

Avoid: a method signature alone, an implementation sketch

Taught in: lessons 0055, 0054

Responsibility

The knowledge and decisions a component owns: what it knows, what it may change, and what it decides. Assigning responsibilities — who knows, who does, who decides — is how boundaries are found before structure exists. (GRASP, Wirfs-Brock)

Avoid: "role" (softer), a task list

Taught in: lesson 0053

Domain invariant

A rule the domain cannot violate, enforced by the domain itself — not by callers' good behavior. Example: an order can never be confirmed twice.

Avoid: business rule (weaker: often means "policy")

Taught in: lesson 0011

Ubiquitous language

The vocabulary shared by domain experts and developers, precise enough to encode in code and tests. When a word means different things to different people, that is a boundary, not a synonym problem.

Avoid: "business speak", one global glossary across contexts

Taught in: lesson 0052

Value object

An immutable object whose identity is its value: two instances with equal fields are interchangeable. Safe to share, trivial to test.

Avoid: mutable DTOs, "entity-lite"

Taught in: lesson 0012

Entity

An object with a continuous identity across changes, tracked over time.

Avoid: "model" (overloaded), "record"

Taught in: lesson 0012

Aggregate

A cluster of domain objects treated as one unit for changes, with a single root that guards the invariants of the whole cluster.

Avoid: aggregate root (the root is one part; the aggregate is the cluster)

Taught in: lesson 0012

Consistency boundary

The set of facts that must change atomically for a hard invariant to hold. A rule spanning boundaries must instead be stated as a reconciliation condition with a time bound, detection, recovery, and ownership.

Avoid: "transaction scope" (its implementation), "everything in one database"

Taught in: lessons 0055, 0012

Repository

A domain-facing collection-like interface for retrieving and persisting aggregates, hiding the storage technology behind it.

Avoid: "DAO" (data-oriented, leaks storage thinking), repository leaking query APIs

Taught in: lesson 0013

Unit of work

The object that owns a transaction's boundary: what is written together, committed together, and rolled back together. Repositories operate inside it; the domain never sees it.

Avoid: save() scattered through the domain, autocommit-per-call

Taught in: lesson 0013

Law of Demeter

A method should only talk to its immediate neighbors: itself, its own fields, its arguments, objects it creates, and the direct members of its own collection. No chain-walking into strangers.

Avoid: "train wrecks" like a.b().c().d(), the principle of least knowledge

Taught in: lesson 0003

Tell, Don't Ask

Ask an object to do something for you instead of interrogating its state and doing it yourself. The natural companion of the Law of Demeter.

Avoid: getter chains, "ask, then act" sequences

Taught in: lesson 0003

Train wreck

A chain of calls that walks through objects the caller does not own — order.customer.address.city. The caller now depends on the internal geography of three objects, and any restructuring of them breaks it.

Avoid: “fluent interface” (a builder returning self is not a wreck)

Taught in: lesson 0003

Composition

Building behavior by holding objects and delegating to them, rather than inheriting from them.

Avoid: "has-a" (shorthand only); composition does not mean "put everything in one class"

Taught in: lesson 0007

Strategy pattern

Extracting a varying behavior behind an interface so the behavior can be swapped at runtime without touching its caller.

Avoid: "policy" (same shape, different name)

Taught in: lessons 0004, 0008

Higher-order function

A function that takes or returns a function. In Python it is the cheapest strategy interface there is: no protocol, no class, no registration.

Avoid: a one-method class used once

Taught in: lesson 0016

Protocol

A structural interface in Python: an object conforms to it by having the right methods, no inheritance required.

Avoid: "duck typing" (untyped protocols), abstract base class (nominal, heavier)

Taught in: lesson 0017

Read model

A representation of data shaped for a specific query, kept separate from the write model that enforces invariants on the way in. It can denormalize, precompute, and lag reality slightly, because its job is answering questions fast, not guarding rules.

Avoid: “the database” (conflates read and write shape), one model exposed for both directions

Taught in: lesson 0013

Structural typing

An object conforms to a type by having the right methods and attributes, not by declaring inheritance from it. Python's typing.Protocol makes this checkable statically without forcing a class hierarchy on unrelated implementations.

Avoid: “duck typing” (the untyped, unchecked version of the same idea)

Taught in: lesson 0017

Parameter object

A small class with no behavior, whose only job is to hold values that always travel together as one argument instead of three or four positional parameters. It stops a signature from growing every time a new related value shows up.

Avoid: a bag of unrelated booleans, “just add another parameter”

Taught in: lesson 0015

Optimistic locking

Concurrency control that reads a version marker with the data and rejects the write if the marker has moved, instead of holding a lock for the duration of the read-modify-write. It fails loudly on conflict rather than silently overwriting.

Avoid: “just retry the write” without checking the version, treating SELECT FOR UPDATE as the only option

Taught in: lesson 0055

Reconciliation condition

A rule that is allowed to be false for a bounded, understood window because enforcing it everywhere at once is too expensive — paired with a detector that notices the gap, a repair that closes it, and an owner accountable for both. The gap is designed, not tolerated by accident.

Avoid: “eventual consistency” used as if it needed no detector or owner, an unmonitored discrepancy

Taught in: lesson 0055

Fragile base class problem

A base class changes one of its own methods, and that change silently breaks subclasses that overrode a different method but relied on the old internal call pattern. Inheritance exposes internals that composition would have kept hidden.

Avoid: “it's just a bug in the subclass” (the base's internal change is the actual cause)

Taught in: lesson 0007

Liskov substitution principle

Anything that was true of the base type — its preconditions, postconditions, and invariants — must stay true of every subtype. A subclass that narrows what it accepts or weakens what it guarantees is not a subtype, whatever the class hierarchy claims.

Avoid: “IS-A” as a sufficient test (syntax, not behavior), overriding a method to throw “not supported”

Taught in: lesson 0007

Middle man

A class whose methods mostly just forward the call to another object with no added logic. It is the failure mode you get from over-applying the Law of Demeter — hiding a train wreck by inserting a layer that repeats it, instead of moving the behavior to where the data lives.

Avoid: “just add a wrapper” as an automatic fix for chained calls

Taught in: lesson 0003

Dependencies and boundaries

Who is allowed to know about whom, and where that rule is written down.

Dependency direction

Which way arrows point between modules. Well-directed dependencies point inward: domain code depends on nothing; infrastructure depends on domain.

Avoid: upward dependencies, dependency cycles

Taught in: lesson 0009

Port

An interface on the edge of a module that defines what the module needs from the world (driven port) or offers to it (driving port). The domain defines the ports; the world provides the adapters.

Avoid: interface owned by the infrastructure

Taught in: lessons 0009, 0023

Adapter

Code that translates between a port (our interface) and a concrete external thing — a database, an API, a file format — so the external thing never touches the domain.

Avoid: wrapper (when the translation is cosmetic), leaky adapter

Taught in: lessons 0008, 0023

Composition root

The single place — usually one function near the program's entry point — where every concrete adapter is constructed and injected. Nothing else in the system names a technology.

Avoid: service locator, ambient container, “wiring everywhere”

Taught in: lessons 0019, 0023

Anti-corruption layer

An adapter at the edge of a bounded context that translates another context's vocabulary into this one's, so a foreign model never leaks inward. (Evans)

Avoid: “just import their types”, a shared DTO package

Taught in: lesson 0036

Bounded context

The boundary within which one model and one vocabulary are consistent. The same word may mean different things in two contexts — and that is the signal to keep them apart.

Avoid: “the one true model”, a global schema

Taught in: lesson 0036

Context map

The diagram of bounded contexts and the relationships between them — partnership, shared kernel, customer/supplier, conformist, anti-corruption layer. It is the boundary evidence for modules and services.

Avoid: "architecture diagram" (too broad), unlabelled boxes and arrows

Taught in: lesson 0053 (optional refinement)

Shared kernel

The small, stable set of concepts two contexts genuinely share and agree to change together. Integration chosen on purpose, not integration by accident.

Avoid: a “core” or “common” package that only grows

Taught in: lesson 0036

Control coupling

One module steering another's internal path with a flag or mode argument, so the caller must understand the callee's branches. The usual fix is to inject the behaviour instead.

Avoid: boolean parameters, mode="..." strings

Taught in: lesson 0016

Global coupling

Dependence on shared, reachable-from-anywhere state or services (singletons, module globals, ambient context). Changes to one consumer affect all consumers — silently.

Avoid: "ambient state", hidden global dependencies

Taught in: lesson 0019

Shared state

State that more than one component reads or writes. The owner is whoever is responsible for its correctness; unowned shared state is the source of most concurrency bugs.

Avoid: "global state" (a species, not the genus)

Taught in: lesson 0020

Fitness function

An automated check that an architectural property still holds — a test that fails the build when a dependency arrow, a layer rule, or a latency budget is violated. (Ford, Parsons & Kua)

Avoid: a README rule, a convention nobody enforces

Taught in: lesson 0022

Conway's law

Systems tend to take the shape of the communication structures of the organizations that build them. Treated as a design input it makes team boundaries an architecture decision; ignored, the architecture is decided by the org chart anyway.

Avoid: “reorg and it will fix itself”, inverse Conway as a slogan

Taught in: the multi-team architecture supplement

Team API

The surface one team offers another: its code and service interfaces, but also how work is requested, who decides what, and how quickly it answers. Teams integrate through this the way modules integrate through contracts — and an undocumented one costs the same as an undocumented module.

Avoid: org chart, “just ping them”, a shared backlog

Taught in: the multi-team architecture supplement

Contract test

One shared test suite, written once against the port, that every adapter implementing that port must pass. It is what stops “the interface says X” from meaning something different in each implementation.

Avoid: testing each adapter against its own bespoke suite, trusting a shared abstract base class alone

Taught in: lesson 0017; run across every port by the lab's fitness functions

Authoritative source

The one system entitled to change a given fact. Every other copy of that fact is a cache, however current it looks, and a disagreement is resolved by asking the authoritative source, not by picking whichever copy is present.

Avoid: “the database” (there may be several), “the latest write” as a stand-in for authority

Taught in: lesson 0020

Last-write-wins

A conflict resolution rule that keeps whichever write has the latest timestamp and discards the other, silently. It enforces no invariant about what the discarded write meant — it is a default for when nobody has decided who owns the fact, not a design choice.

Avoid: “conflict resolution” as if it always applies, treating clock skew as a solved problem

Taught in: lesson 0020

Ratchet

A fitness function that freezes today's count of a known violation and fails the build only if that count goes up. It lets a team ship without a full cleanup while guaranteeing the problem never gets worse — and gives a visible number to bring down over time.

Avoid: a violation count nobody tracks, “we'll clean it up eventually” with no gate

Taught in: lesson 0022

Runtime, failure and evolution

What the system does when the world misbehaves, and how it changes without stopping.

Fail-fast

Failing as close to the cause as possible, loudly and immediately, instead of letting a bad value travel and corrupt far from its origin.

Avoid: silent None, ignored errors, deferred exceptions

Taught in: lessons 0014, 0021

State machine

An explicit model of an entity's legal states and the commands that move between them, each with an actor and a rule. It turns "status" from a free-form column into guarded behavior.

Avoid: "status field", a free-form enum

Taught in: lesson 0054

Event-driven architecture

Components communicate by publishing and consuming events rather than by calling each other directly, so producers don't know their consumers.

Avoid: "event-based" (fine), "message-driven" (a sibling, not the same)

Taught in: lesson 0025

Event sourcing

Persisting the stream of facts (events) that happened, and deriving current state by replaying them. The event log is the source of truth; current state is a projection. Justified by audit, history, or replay needs, not fashion.

Avoid: "audit table", "just keep a log"

Taught in: lessons 0054, 0058

Message bus

A channel that routes events or commands from publishers to subscribers, decoupling the two sides.

Avoid: "event bus" (a species of message bus)

Taught in: lesson 0025

Idempotent

An operation that produces the same end state whether it runs once or five times. Idempotence is what makes at-least-once delivery survivable and retries safe.

Avoid: “safe to retry” (true only once the operation is idempotent)

Taught in: lessons 0031, 0032

Idempotency key

A caller-generated identifier for one intent, reused across every retry of that intent, so the receiver can return the first answer instead of acting twice.

Avoid: a fresh id per attempt (which buys nothing)

Taught in: lesson 0032

Dead-letter queue

Where a message goes after its handler has failed its allotted attempts. It only counts as a design if a human actually watches it.

Avoid: infinite retries, silent drops

Taught in: lesson 0031

Correlation id

An identifier attached to an event and to every log line produced while handling it, so one workflow can be followed across handlers that share no call stack.

Avoid: “grep the timestamps”

Taught in: lesson 0031

Eventual consistency

A guarantee that replicas converge if writes stop — with no promise about what a read sees in the meantime. Useful when a stale answer is cheap; dangerous when the reader will act on it as if it were current.

Avoid: “inconsistent” (it is a guarantee, not the absence of one)

Taught in: lesson 0032

Tolerant reader

A consumer that requires only the fields it uses and ignores everything else, so producers can add fields without a coordinated release.

Avoid: strict schema validation on inbound events

Taught in: lesson 0033

Characterization test

A test that records what code currently does, not what it should do — written to lock behaviour before restructuring unfamiliar or AI-generated code. (Feathers)

Avoid: “I'll refactor first and test after”

Taught in: lessons 0005, 0037

Strangler fig

A pattern for replacing a system incrementally: route new behavior around the old implementation, growing the new one until the old one can be deleted.

Avoid: "big bang rewrite" (the anti-pattern)

Taught in: lesson 0035

Branch by abstraction

A safe transition technique: insert an abstraction over a component, migrate all users to it, then swap the implementation behind it.

Avoid: long-lived feature branches (the coordination cost is the point)

Taught in: lesson 0035

Expand / contract

A staged compatibility technique: add the new form, write both, backfill and verify, switch reads, then stop old writes. Removing the old form is a later destructive step after a retention window and recovery decision. Also called parallel change.

Avoid: the one-step rename, the “quick” migration

Taught in: lesson 0035

Feature flag

A runtime switch that separates deploying code from releasing behaviour and can limit further exposure. It does not undo data or external side effects. A flag that outlives its transition becomes configuration debt.

Avoid: permanent flags, flags used as a state model

Taught in: lesson 0035

Deployment pipeline

The automated path from committed code to production: build, test, package once, then promote that artifact through environments. Its job is to make deployments repeatable, observable, and recoverable.

Avoid: "deploy script" (a fragment), manual release checklists

Taught in: lesson 0060

Config graveyard

The accumulated settings nobody has ever varied: knobs added “just in case”, each one documented, validated, tested and combinatorially possible — for no measured variation at all.

Avoid: “configurable”, “flexible” (as unexamined virtues)

Taught in: lesson 0029

Technical-debt ledger

A written record of a shortcut taken on purpose: what was borrowed, the interest (the recurring cost while it stands), and the trigger that repays it. Debt without a ledger is indistinguishable from a mistake, and gets treated as one.

Avoid: a “tech debt” epic, a refactoring wish list, “we’ll clean it up later”

Taught in: lesson 0038 and the brownfield modernization case

Trade-off

A decision between forces that cannot both be maximized. The craft is making the trade-off explicit, deliberate, and reversible — not avoiding it.

Avoid: "best practice" (implies no cost), "silver bullet"

Taught in: lessons 0027, 0038

Poison message

An input that fails its handler on every retry, not because of a transient fault but because the message itself is malformed or unhandleable. Left in an ordinary queue it blocks everything behind it; the fix is to detect it and route it to a dead-letter queue after a bounded number of attempts.

Avoid: “just retry harder”, unlimited retry loops

Taught in: lesson 0014

Graceful degradation

Continuing to run with an optional capability missing or failed, in a way that is visible rather than pretending nothing happened. The system does less, on purpose and observably, instead of failing entirely or lying about what it delivered.

Avoid: silently returning stale or default data with no signal, “fail open” used as a synonym

Taught in: lesson 0014

At-least-once delivery

A broker guarantee that a message will be delivered one or more times, never zero — which means a handler can receive the same message twice and must be written to tolerate it. It is the reason idempotency is a delivery-layer requirement, not an optional nicety.

Avoid: “exactly-once” assumed by default, a handler written as if delivery were guaranteed single

Taught in: lesson 0025

PACELC

An extension of the CAP theorem: if the system is Partitioned, choose Availability or Consistency; Else — even with no partition — choose Latency or Consistency. It names the trade-off CAP leaves out: normal operation still forces a choice between a fast answer and a fully consistent one.

Avoid: “CAP” cited as if it covered ordinary, unpartitioned operation

Taught in: lesson 0032

Consumer-driven contract

A test, owned and written by the consumer, that runs against the producer's build and fails it if the producer breaks something the consumer actually relies on. It moves “will this change break anyone” from guesswork to a build result.

Avoid: a producer-authored contract the consumer never reviewed, manual “check with the other team” coordination

Taught in: lesson 0033

Read-your-writes consistency

A guarantee that a user who just made a change will see that change on their own next read, even if other users might still see a stale replica. It is a narrower, cheaper promise than full consistency, and often the only one that actually matters to the person waiting.

Avoid: “strong consistency” claimed when only this narrower guarantee is provided

Taught in: lesson 0032

Reconciliation check

Recomputing a result through an independent path and reporting where it disagrees with the original, rather than trusting either path alone. It catches the class of bug that passes every test but silently drifts from truth in production.

Avoid: “the tests pass” treated as proof of production correctness, no independent recomputation ever run

Taught in: lesson 0037

Detection time

How long a defect can hide before anyone notices it. It multiplies the cost of every other reversibility decision: a cheap-to-fix bug that hides for months does more damage than an expensive-to-fix one caught in code review.

Avoid: “we'll catch it in QA” without asking how long undetected defects actually survive

Taught in: lesson 0037

Golden master

A characterization test that asserts byte-for-byte equality against a previously recorded output, usually of a whole projection or report, rather than checking individual fields. It is coarse but cheap insurance against unintended change in code nobody fully understands yet.

Avoid: hand-written expected values for legacy output no one can explain, skipping characterization because “it's too big to test”

Taught in: the brownfield modernization case

Expected failure (xfail)

A test marked as a known-red result and reported as declared, tracked debt rather than a build failure — but one that fails the suite the moment it unexpectedly starts passing, forcing someone to notice and remove the marker. It keeps a known gap visible without letting it block delivery.

Avoid: a skipped test nobody revisits, commenting out a failing assertion

Taught in: the lab's fitness functions

Open vs closed enum

Whether consumers of a value set must handle values they have never seen (open) or may assume the set is complete (closed). Which one a field is changes whether adding a new value is a safe addition or a breaking change — and it has to be decided and documented, not discovered when a client crashes.

Avoid: adding a new enum value without checking who assumed the set was closed

Taught in: the capstone packet's state and contract review

Blue/green deployment

Running two complete environments and switching a router from one to the other to release, so rollback is switching the router back. It is reversible for the code but not for anything already written to shared data by the new version.

Avoid: “blue/green” treated as reversible for data as well as code

Taught in: lesson 0060

Transactional outbox

A pattern that persists the intent to publish a message in the same transaction as the business change, then has a separate worker deliver it from that table. It avoids the gap where a database commit succeeds but the matching event is lost, or the event goes out for a commit that then rolls back.

Avoid: publishing directly from application code inside the same request, “dual write” without a shared transaction

Taught in: lesson 0059

Compensating action

A new, forward-moving business fact that offsets an action already taken, used when the original action cannot be undone. A refund compensates a charge; it does not erase that the charge happened.

Avoid: “rollback” applied to an action with real-world side effects, deleting the record of what occurred

Taught in: lesson 0054

Batch size

The amount of change released in a single deployment. Larger batches sit behind higher release risk and slower diagnosis, because a failure has more candidate causes to sort through; the lever is usually available even when release frequency feels fixed.

Avoid: “we can't release more often” without examining what is bundled into each release

Taught in: lesson 0035

Effective configuration

The full set of settings a process actually runs with, after defaults, files, environment variables, and flags are all merged and overridden. It is frequently not what any single config file says, which is why “check the config” is not the same as knowing what is running.

Avoid: reading one config source and assuming it is the whole answer

Taught in: lesson 0029

Initiative leadership

The vocabulary for turning an ambiguous brief into measurable system and team decisions.

Product outcome

An observable change in user or business behaviour, stated with a baseline, target, cohort, and time boundary. It preserves freedom to change the solution while holding the initiative accountable for its effect.

Avoid: feature, deliverable, launch date, “ship the portal”

Taught in: lesson 0039

Assumption map

A map of beliefs by impact if false and strength of evidence, often grouped as value, usability, feasibility, and viability. The high-impact, weak-evidence corner becomes the discovery priority.

Avoid: risk list with no evidence axis, brainstorm vote

Taught in: lesson 0040

User story

A placeholder for a conversation about one user's need and the behaviour that may satisfy it. The sentence alone is not a requirement; examples provide confirmation.

Avoid: mini-specification, task disguised as user value

Taught in: lesson 0042

Story map

A two-dimensional product map: user activities run left to right as a journey, while alternatives and detail run downward. Horizontal lines cut coherent release or learning slices across the journey.

Avoid: flat backlog, dependency graph, feature inventory

Taught in: lesson 0042

Vertical slice

A narrow piece of observable behaviour that crosses the necessary technical layers end to end. It is small by cohort, rule, variation, or quality threshold—not hollowed into disconnected component tasks.

Avoid: “backend story”, schema-only milestone, horizontal layer

Taught in: lesson 0042

Architecture driver

A functional need, quality attribute, constraint, or risk important enough to shape system structure. It distinguishes between plausible designs; most requirements do not.

Avoid: every requirement, technology preference, generic “best practice”

Taught in: lesson 0043

Quality-attribute scenario

A measurable statement of how a system must respond: source, stimulus, environment, affected artifact, response, and response measure. It turns “fast” or “available” into design and test input.

Avoid: vague non-functional requirement, unmeasured “-ility”

Taught in: lesson 0043

Blast radius

The people, operations, data, components, or requests exposed when a change or failure goes wrong. Reducing blast radius makes learning and reversal cheaper.

Avoid: impact (too vague), server count alone

Taught in: lessons 0043, 0049

Architecture Decision Record

A short, durable record of one consequential decision: context, forces, credible options, decision, consequences, dissent, and a revisit trigger. A later decision supersedes rather than edits it.

Avoid: architecture novel, meeting transcript, rewritten history

Taught in: lesson 0046

Walking skeleton

The thinnest production-shaped end-to-end implementation: real build and deployment, representative boundaries and storage, telemetry, and tiny behaviour. It proves the delivery path before behavior fills it.

Avoid: throwaway prototype, complete infrastructure phase

Taught in: lesson 0047

Decision rights

An explicit statement of who makes the final call in a decision domain and whose advice they must seek. It enables broad collaboration without turning consensus into a veto.

Avoid: RACI for every task, authority left implicit

Taught in: lessons 0039, 0048

Work in progress

Work the team has started but not finished into evidence. Limiting it reduces queues, context switching, and elapsed time; swarming values system flow over individual utilization.

Avoid: everyone must stay busy, one item per specialist

Taught in: lesson 0048

Rollout gate

A decision boundary between exposure stages with explicit entry evidence, observation window, advance threshold, stop threshold, decider, and reversal. It turns launch into a controlled sequence.

Avoid: “looks good”, arbitrary percentage ramp, calendar-only gate

Taught in: lesson 0049

Cost of delay

The value lost for every unit of time an outcome arrives later, stated in money per week. It converts sequencing arguments from volume (“everyone says theirs is urgent”) into arithmetic, and it is what makes a queue visibly expensive.

Avoid: priority, “high impact”, deadline pressure

Taught in: the architecture economics supplement

Total cost of ownership

Everything a decision costs across its life: build or licence, operation, on-call, the coordination it imposes between teams, and eventual replacement. Comparing options on purchase price alone reliably picks the more expensive one.

Avoid: cost (unqualified), sticker price, story points

Taught in: the architecture economics supplement

Threat model

A structured answer to “what can go wrong here”: the data flows, the trust boundaries they cross, the abuse cases, and the mitigations that will actually be built. A design activity done with the team, not a review performed on it afterwards.

Avoid: penetration test, compliance checklist, “we use HTTPS”

Taught in: the security, privacy and accessibility supplement

Guardrail

A measure that an initiative commits not to make worse, stated with a threshold and an owner who watches it. It lets a team move fast on the outcome it is chasing while keeping an explicit promise about what it will not sacrifice to get there.

Avoid: an unstated assumption that nothing else will regress, a metric tracked with no threshold or owner

Taught in: lesson 0039

Anchoring

The first idea spoken in a discussion conditions every contribution that follows, whether or not it was any good. Facilitation techniques that collect ideas independently before anyone speaks exist specifically to defeat it.

Avoid: open-floor brainstorming with no independent generation step first

Taught in: lesson 0040

Holdback cohort

A population deliberately kept unexposed to a change so the exposed population's outcome can be read as a comparison against something, not just a before-and-after on a moving baseline. Without it, a metric's normal drift can be mistaken for the change's effect.

Avoid: “holdback control” (the same concept; prefer this term for consistency), a rollout with no unexposed comparison group

Taught in: lesson 0049 and the capstone packet's rollout section

Canary release

Releasing to a small, measured cohort first, with an explicit stop rule agreed before exposure begins. The cohort size and the stop rule are what make it a canary release rather than an ordinary staged rollout with no plan for what happens if it goes wrong.

Avoid: a small rollout with no pre-agreed stop threshold, “we're watching it” as the entire plan

Taught in: lesson 0049

Little's law

Average cycle time equals work in progress divided by throughput. It is the arithmetic reason that limiting WIP shortens how long any one thing takes to finish, without needing anyone to work faster.

Avoid: “just prioritize better” as a substitute for reducing WIP

Taught in: lesson 0048

Spike

A timeboxed investigation into a single question, with the result format and the discard rule for the code decided before it starts. A spike answers a question; it does not ship, and code written during one is thrown away rather than hardened in place.

Avoid: a spike that quietly becomes production code, an open-ended investigation with no timebox

Taught in: lesson 0046

Release train

A fixed, externally imposed deploy schedule that every team's change must fit around. It bounds how much change can go out at once and how fast a bad change can be rolled back, independent of how fast any one team can build.

Avoid: “we'll just deploy whenever it's ready” where a train schedule actually governs release

Taught in: lesson 0047

Reversal rehearsal

A timed practice run of the rollback path, done before each exposure stage of a rollout rather than left untested until a real incident forces it. A rollback plan that has never been executed is a hypothesis, not a safety net.

Avoid: a rollback plan that exists only as a paragraph in a document

Taught in: lesson 0049 and the artifact template pack's rollout contract

Manual seam

A step in a workflow deliberately left to a person instead of automated, with a stated capacity, an owner, and a trigger for when it should be removed. It is a legitimate design choice when the volume does not yet justify automation — as long as those three things are written down.

Avoid: an unstated manual step nobody owns, “temporary” workarounds with no removal trigger

Taught in: the artifact template pack's story map and example card

Evidence milestone

A milestone named for what becomes demonstrable at that point — a real request flowing end to end, a specific decision made — never for a percentage of work done. It forces a delivery map to say what anyone could go look at, not how much effort has been spent.

Avoid: “50% complete”, a milestone named after a task list item rather than an observable capability

Taught in: lesson 0047

STRIDE

A checklist of threat categories — Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege — walked over each data flow in a system to find where it can be attacked. It structures a threat model so coverage does not depend on which attacks happen to come to mind.

Avoid: an ad hoc list of “things that could go wrong”, a threat model with no per-category pass

Taught in: the security, privacy and accessibility supplement

Object-level authorization

Checking not just whether a principal may call an operation, but whether they may act on this specific object — this order, this account, this document. An API that checks the former and not the latter lets any authenticated user reach anyone else's data by changing an id.

Avoid: authentication mistaken for authorization, “the endpoint requires a login” treated as sufficient

Taught in: the security, privacy and accessibility supplement

Trust boundary

A point where data crosses between two parties who trust each other to different degrees — a client and a server, two services, a service and a third party. Every trust boundary is a place validation and authorization actually have to happen, because whatever crossed it cannot be trusted to have already been checked.

Avoid: validating once at the perimeter and trusting everything internal forever after

Taught in: the security, privacy and accessibility supplement

Data minimization

Not collecting or retaining a field you do not need. A field that was never stored has no retention policy to write, no access control to get wrong, and no breach exposure — it is the cheapest privacy control there is, because it is the absence of a liability rather than a defense of one.

Avoid: “we might need it later” as a reason to collect it now, retention policies used as a substitute for not collecting

Taught in: the security, privacy and accessibility supplement

Modernization, economics, and leadership

The vocabulary for changing a system you cannot stop, and for the organizational and economic reasoning that surrounds the decision.

Upgrade tax

The recurring cost of staying on a vendor's or platform's release cadence — migration work, breaking-change churn, retesting — paid whether or not the new version offers anything the team wants. It belongs in the total cost of ownership of a build-vs-buy decision, not as a one-time cost.

Avoid: comparing license price alone, “buy” decisions that never price in future migrations

Taught in: lesson 0027

Exit cost

What it costs to leave a dependency once adopted: building a second adapter, exporting data in a usable form, and verifying the replacement actually works. A dependency with a high exit cost has effectively been chosen for good, whatever the contract says about notice periods.

Avoid: “we can always switch later” without pricing what switching later would take

Taught in: lesson 0027

Sprout and wrap

Two techniques for adding tested behavior to code that resists testing: sprouting a new, tested method or class that the legacy code calls into, or wrapping an existing call with new tested logic around it. Both add new, safe surface without requiring the untestable code to be understood first.

Avoid: editing the untested method directly “just this once”, a full rewrite treated as the only alternative

Taught in: the brownfield modernization case

Enabling point

The place in existing code where a seam's behavior actually gets chosen — a single call, a single construction site. A seam without an identified enabling point is not yet usable: you know where behavior could vary, but not where to intervene to make it vary.

Avoid: naming a seam without locating the one place that decides it

Taught in: the brownfield modernization case

Dual-write window

The stage of an expand/contract migration where both the old and new data forms are written in a single transaction, so reads can switch to the new form and switch back if something is wrong — because the old form is still being kept current underneath.

Avoid: switching reads to the new form before writes are dual, treating dual-write as the finish line rather than a stage

Taught in: the brownfield modernization case

Compensating control

A safeguard your own team owns and operates that offsets a risk introduced by a dependency you do not control — a validation layer around a flaky third party, a circuit breaker around an unreliable service. It substitutes for fixing the dependency when fixing it is not an option.

Avoid: accepting a dependency's risk with no mitigation because “it's their problem”

Taught in: the brownfield modernization case

Repayment trigger

An observable event — not a calendar date — that makes a technical-debt ledger item due: a traffic threshold crossed, a second team blocked by it, a vendor deprecation. Dates get pushed; a trigger tied to an observable fact does not.

Avoid: “we'll fix it next quarter” as the only trigger a debt item gets

Taught in: the brownfield modernization case's debt ledger

Superseding ADR

A new Architecture Decision Record that replaces an earlier one's decision while leaving the earlier record's text untouched. The history of what was believed and why stays intact; only the current answer changes, and anyone can see the sequence that led there.

Avoid: editing an old ADR in place to reflect the new decision, deleting a superseded record

Taught in: the decision-change simulations

Admission control

Refusing new work once a guardrail is reached, explicitly and visibly, instead of letting it queue silently until something else fails. It trades a clear, immediate rejection for an invisible, delayed one.

Avoid: unbounded queues that fail somewhere else instead, silently dropping requests under load

Taught in: the decision-change simulations

CD3 — Cost of Delay Divided by Duration

The ratio of an item's cost of delay to how long it will take to finish. Sequencing a single queue by CD3, highest first, is the rule that maximizes total value delivered over time — it is what turns “everything is urgent” into an actual ordering.

Avoid: sequencing by cost of delay alone, ignoring how long each item takes

Taught in: the architecture economics supplement

Compatibility window

A stated period during which a producer commits to serving both the old and new shape of an interface, so consumers have a bounded, known amount of time to migrate. An unstated window is really a promise to serve the old shape forever, because no consumer knows when it is safe to stop relying on it.

Avoid: deprecating a shape with no date attached, “we'll give people time” left unspecified

Taught in: the multi-team architecture supplement

Advice process

A decision-rights model where anyone may decide in their own area of authority, provided they first seek advice from those affected and those with relevant expertise, and record what they heard. It scales autonomy without needing every decision to become a consensus meeting.

Avoid: unilateral decisions with no advice sought, consensus required for every call

Taught in: the multi-team architecture supplement

Interaction mode

The way two teams work together — collaboration, X-as-a-service, or facilitating — named explicitly, dated, and understood to be temporary rather than a permanent structural fact. The same two teams may need a different mode next quarter, and calling it out is what makes changing it possible.

Avoid: an interaction mode that is never named and so never revisited

Taught in: the multi-team architecture supplement

Forecast range

A prediction stated as a confidence level, an interval, the variable that is driving the uncertainty, and the date at which the interval will narrow. It replaces a single confident-sounding date with something a listener can actually act on.

Avoid: a single point estimate presented with no uncertainty, “trust me” in place of a stated confidence

Taught in: the technical influence supplement

Disagree and commit

Recording a dissent in the dissenter's own words, alongside a specific trigger that would reopen the decision, and then executing the decision as made. It preserves the disagreement as evidence instead of pretending consensus existed, while still letting the team move.

Avoid: silence mistaken for agreement, a decision reopened by anyone at any time with no stated trigger

Taught in: the technical influence supplement

DRI — Directly Responsible Individual

The person accountable for moving one specific decision to a close, distinct from whoever has authority over the broader area or does the most work on it. Naming a DRI answers “who makes this call happen” when a decision-rights model alone leaves it ambiguous which person, today, is the one to chase.

Avoid: a decision with no single accountable person, mistaking a DRI for the only person allowed to have an opinion

Taught in: lesson 0048

Practice, assessment and evidence

The vocabulary for showing that the judgment above is real, in a form somebody else can review.

Capstone

The complete worked initiative packet — frame through closeout — that a learner produces and then compares against a strong and a deliberately weak version of the same problem. It is the course's evidence artifact: judgment made reviewable.

Avoid: final project, portfolio piece (that is what it becomes, not what it is)

Taught in: the worked capstone

Rubric (behaviourally anchored)

A scoring guide whose levels describe observable behaviour rather than quality adjectives: Developing, Practicing, Lead-ready, Architect-ready. Every score cites evidence in the learner's own work, and more than one design can score well.

Avoid: checklist, grade, a job title used as a score

Taught in: the capstone rubric

Decision-change simulation

An exercise that supplies incomplete information, requires a committed direction, and then changes the evidence — a vendor misses its latency target, the deadline loses four weeks, volume arrives ten times over forecast. It scores coherent adaptation, not hindsight-perfect design.

Avoid: case study with one right answer, post-mortem, “what would you have done”

Taught in: the decision-change simulations

Entry diagnostic

Scenario questions that test applied judgment rather than self-reported familiarity, used to route a learner to the earliest phase where their judgment stops being consistent. Its exit counterpart uses comparable scenarios, so growth is measured rather than felt.

Avoid: self-assessment survey, “rate your confidence 1–5”, prior job titles

Taught in: the entry diagnostic

Anonymization

Stripping the identity of the organization, the people, and enough implementation detail from a real workplace artifact that it can be shared and discussed, while keeping the forces and trade-offs that made the decision hard intact. An anonymized artifact that also removes the trade-offs is no longer useful evidence of judgment.

Avoid: renaming the company but leaving other identifying detail in place, deleting so much detail that the actual decision disappears

Taught in: the portfolio guide

Behaviorally anchored rating

A scoring level defined by what the work actually shows — the options compared, the evidence cited, the consequences named — rather than by an adjective like “good” or “excellent” left to the rater's judgment. Two different raters looking at the same evidence should reach the same level.

Avoid: a rating scale of unanchored adjectives, “I know it when I see it” grading

Taught in: the capstone rubric

Adversarial prompt

A prompt to an AI collaborator that demands an enumerated sequence of steps and the mechanism behind a claim, rather than accepting a summarized conclusion. It is a technique for getting past confident-sounding output to the reasoning that can actually be checked.

Avoid: accepting an AI-generated conclusion because the phrasing sounds authoritative

Taught in: the AI collaboration supplement

Evidence rule

AI-generated artifacts — analyses, summaries, generated tests — never substitute for evidence from a real user, the actual domain, or production. They can accelerate reaching that evidence; they cannot stand in for it.

Avoid: citing an AI-generated analysis as if it were user research, treating a generated test suite as proof of correctness

Taught in: the AI collaboration supplement