Taxonomy

Six levels, each a definition with criteria for what belongs to it. Every entry below the root names its parent one level up, so every rule traces back to a value. Standards that a linter enforces live in the semgrep repository.

  1. Value

    Terminal human intent

    • Include

      Asking ‘Why?’ exits this taxonomy and collapses into ethics, biology, or theology. The fractal ends here.

    • Include

      Speaks of people and what they care about.

    • Include

      A disposition or attitude we hold.

    • Include

      A weighing with nothing above it to decide it. A value is what decides the weighings below.

    • Include

      Answers why we chose the axioms we hold and not others.

    • Exclude

      Is about software, a system, or a method. Mentioning one in passing does not make it so.

  2. Axiom

    A truth we hold.

    • Include

      Expresses an irreducible truth. Asking ‘Why?’ of it has no answer; asking why we hold it rather than another truth leads straight to a value.

    • Include

      Held beyond argument: a stone tablet. It cannot be moved down the ladder.

    • Include

      Stays true when ‘code’ is replaced by any other artifact.

    • Include

      Carries no marker.

    • Exclude

      Names a software concept.

    • Exclude

      Follows from another axiom.

    • Exclude

      Explains why it holds. The explanation belongs to a rationale below it.

    • Exclude

      Addresses how people should act.

  3. Rationale

    How an axiom is turned into a principle.

    • Include

      Requires a Document reference to explain.

    • Include

      Weighs two goods against each other, either of which could be chosen, or explains a mechanism. Every ‘X over Y’ between two goods is a rationale.

    • Include

      A weighing is measured against the level above: the parent decides which side wins. A weighing the parent cannot decide points at a defect in the parent.

    • Include

      The losing side of its trade-off is a candidate code smell.

    • Include

      Its solutions say how to apply it, opened by SHOULD or MAY. A preference, an ‘X over Y’ that a reviewer cannot answer with violation or not, is a solution here and never a rule.

    • Exclude

      Can be stated in two sentences without loss and weighs nothing.

    • Exclude

      Rejects a smell rather than weighing two goods. ‘Do X, not Y’ where Y is a smell is a principle or a rule.

    • Exclude

      Has no level above it to decide the weighing.

  4. Principle

    A memorable statement of how we code and what we code, such as Don’t Repeat Yourself or Contract First.

    • Include

      Can be expressed in one or two sentences that you can act on or adhere to without having to reason about it, typically ‘given this, do that’ or ‘we do it like this’.

    • Include

      Its name alone is cited from memory in a review, and the name says what to do.

    • Include

      States a stance, applied by understanding the idea behind it. Its violation shows in code as a smell a rule can name.

    • Include

      May enumerate the cases it covers. Enumeration is not reasoning and does not make it a rationale.

    • Exclude

      A name alone, with no statement behind it.

    • Exclude

      Weighs one option against another.

    • Exclude

      Names a technology.

    • Exclude

      Restates its rationale, or carries an enumeration the glossary already holds.

  5. Rule

    A MUST or MUST NOT a reviewer answers on a diff: violation or not.

    • Include

      A Developer answers ‘violation or not?’ on a ten-line diff without understanding the whole system.

    • Include

      Opens with MUST NOT and names the Defined Bad Code it forbids.

    • Include

      Opens with MUST and states the Defined code it requires.

    • Include

      May list the code smells that indicate the rule is being violated.

    • Include

      Where Static code analysis can decide it, a standard implements it for each technology.

    • Exclude

      Names a technology. A statement that names a technology and still holds an instruction without it is split into a rule and a standard.

    • Exclude

      Needs an idea explained to be applied.

    • Exclude

      Restates its principle. A rule that only repeats the principle’s statement adds no question a reviewer can answer.

  6. Standard

    A rule implemented in code for one technology.

    • Include

      Names a language, Framework, Library, or tool.

    • Include

      Static code analysis evaluates it and rejects a violation deterministically in milliseconds.

    • Exclude

      Can be evaluated without knowing the technology in use.

From Values to Standards

ValueSpeed Through Discipline

We don’t “move fast and break things”—we move fast because we build things right. We recognize that skipping tests, security, or rigor in Automation and reproducibility isn’t a shortcut; it’s technical debt. By maintaining a disciplined foundation, we ensure optimal conditions and the highest possible true speed.

Strictness and discipline are the way to efficiency and speed. Strictness and discipline are the same as performance, and Outcome Over Output defines performance.

AxiomSingle Source of Truth

Every piece of information is defined exactly once.

When I have presented one corner of a subject to any one, and he cannot from it learn the other three, I do not repeat my lesson. Analects VII.VIII
RationaleConvention over invention

Code is read far more often than it is written (PEP 8) and maintained by people who did not write it. Following the ecosystem’s conventions and the Surrounding code lets a reader predict structure instead of decoding it. The Rails Doctrine calls it removing the mundane decisions so effort goes to what is new.

PrincipleConvention Over Novelty

Structure follows the conventions of the ecosystem and of the Surrounding code; novelty belongs in the domain solution. Only a Demonstrable standard is a convention.

RuleConsistent with the codebaseMUSTConventions

Follow the Surrounding code where no Demonstrable standard decides the question.

RuleDemonstrable, not recalledMUSTConventions

Point at a Demonstrable standard whenever you invoke a standard as justification. Novel work is not required to cite a standard it does not have.

PrincipleDon't Repeat Yourself

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system (The Pragmatic Programmer, Tip 15).

RuleNo second representationMUST NOTReuse

Add a second Representation of knowledge the codebase already holds.

RationaleIntent lives where it is checked

A comment is prose no tool checks, and it drifts from the code it describes. Knowledge placed where drift is caught stays true: a name appears at every call site, a Failing test turns unfinished work into a red build, an Architecture Decision Record keeps the why of a design with its context. Michael Nygard’s Documenting Architecture Decisions shows the cost of losing that why: teams blindly accept a decision or blindly reverse it.

  • SHOULD

    Name each test after the behaviour it pins, so the tests read as the specification.

PrincipleNo Comments

What a comment would say lives where it is checked. Every Comment intent has such a home, and only a Machine-read comment stays in the code.

RuleNo comments in codeMUST NOTConventions

Comment any version-controlled artifact. Only a Machine-read comment is exempt.

RationaleMake the wrong thing fail

Documents advise; the build decides. Compiler strictness, linters, and thresholds live in the self-testing build (Continuous Integration), where every change, by any Developer, meets the same bar. As in Toyota’s jidoka, an abnormality stops the line instead of travelling downstream. A gate that is relaxed is a broken window: it tells everyone the standard is gone.

  • SHOULD

    Run the same build locally and in the pipeline, so a change meets one bar wherever it runs.

  • SHOULD

    Let each tool write its report untouched, and compare the report against the thresholds in a separate step.

  • SHOULD

    Resolve a Static code analysis warning at its root cause; where the code cannot satisfy a strict rule, seek architectural guidance, never a workaround.

  • SHOULD

    Enable the strictest static-analysis presets and compiler checks the ecosystem offers, so safeguards are enforced without review.

PrincipleThe Toolchain Is the Guardrail

The quality bar is defined once, in the build, and the build makes the wrong thing fail; it is never weakened to let a change through.

RuleNo global lint changesMUST NOTToolchain & Environment

Change global or project-wide Lint rules, except in a Pull request that contains only that Change.

RuleNo global quality changesMUST NOTToolchain & Environment

Change global or project-wide Quality standards, except in a Pull request that contains only that Change.

RuleNo local disabling of lint rulesMUST NOTToolchain & Environment

Disable a Lint rule locally, by a comment, a Pragma, or alike. An exception the team accepts is expressed globally, by a File filter in the lint configuration or alike.

RuleNo committing generated codeMUST NOTToolchain & Environment

Commit Generated code.

RuleStrict presetsMUSTToolchain & Environment

Use the strictest possible Presets on linting and style.

RationaleEnvironment parity

If it works on your machine but not in production, the environment is the bug. Keeping parity between production and test is what guarantees that a verification also holds in production, and that no time goes to hunting bugs that exist only in test. The Twelve-Factor App, X. Dev/prod parity names three gaps that open between the two, in time, in personnel, and in tools, and every gap is a place where a defect hides until the deploy. Closing them means the environment stops being a state each machine has drifted into and becomes a definition every machine is provisioned from: one description, in code, from which local, staging, and production are all built. GitHub’s Scripts to Rule Them All applies the same idea at the entry point: one consistent bootstrap across every project, so a newcomer clones, builds, and tests with a single command instead of a page of steps. A manual step is a second definition of the procedure, kept in the head of whoever last ran it.

  • SHOULD

    Provision every environment, the local one included, from the same infrastructure-as-code definition.

  • SHOULD

    Run the production artifact itself locally and in Integration tests, rather than a lighter stand-in for it.

PrincipleProduction Parity

Tests run the Production code as production runs it.

RuleTest setup leaves production code aloneMUST NOTToolchain & Environment

Alter the behaviour of Production code in Test setup.

PrincipleInfrastructure as Code

Every environment is provisioned from one definition in version control; none is assembled by hand.

RuleOne-command setupMUSTToolchain & Environment

Keep clone, build, and Test of the entire Environment to one documented command.

RuleNo manual environment setupMUST NOTToolchain & Environment

Set up a test or production Environment with a manual step.

RuleTwice is automatedMUSTToolchain & Environment

Script a procedure for Automation the second time it is performed.

RationaleAgree at the boundary

Two sides of a boundary that each define the shape they expect hold two definitions of one thing, and the two drift until the day they disagree in production. One contract, written apart from either side, is the single definition: both sides are derived from it and checked against it, and a disagreement between code and contract is a defect in the code. Bertrand Meyer’s Design by Contract binds client and supplier to one specification, where each party’s obligation is the other’s benefit. The OpenAPI Initiative’s design-first guidance makes the description the contract that the code is validated against in continuous integration, and Protocol Buffers define a structure once and generate every side from it.

  • SHOULD

    Generate both sides of a boundary from the contract rather than write either by hand.

  • SHOULD

    Check the running code against the contract in the build, so a drift fails before it ships.

  • MAY

    Publish the contract on its own, versioned apart from any implementation, so every consumer reads the same definition.

PrincipleContract First

The contract stands above both sides of a boundary: each side is derived from it and conforms to it, and where code and contract disagree, the code is wrong.

RuleShapes live in the contractMUSTContracts

Define a shape that crosses a boundary in the Contract and derive the code on both sides from it.

AxiomShift Left

Do every activity at the earliest point where it can be done.

The mechanic, who wishes to do his work well, must first sharpen his tools. Analects XV.IX
RationaleThe Practical Test Pyramid

Write tests of different granularity, and the higher the level, the fewer the tests: “Write lots of small and fast unit tests. Write some more coarse-grained tests and very few high-level tests that test your application from end to end” (Ham Vocke, The Practical Test Pyramid). Below the unit tests, Yaron Minsky’s “Make illegal states unrepresentable” and Alexis King’s Parse, don’t validate remove whole classes of bugs before a test exists. Lower levels give faster, more precise feedback and leave less to maintain.

PrinciplePush tests down the pyramid

Catch a defect on the lowest level of the Test Pyramid that can catch it.

RuleNo check the type system makesMUST NOTTest Pyramid

Write a Runtime check or a test for what the Type system can reject.

RuleNo test a linter makesMUST NOTTest Pyramid

Write a test for what Static code analysis can reject.

RuleNo narrow integration test for a unitMUST NOTTest Pyramid

Write a Narrow integration test for what a Unit test can catch.

RuleNo integration test for one componentMUST NOTTest Pyramid

Write an Integration test for what a Narrow integration test can catch.

RuleNo end-to-end test for one serviceMUST NOTTest Pyramid

Write an End-to-end test for what an Integration test can catch.

RuleNo manual test for an automated oneMUST NOTTest Pyramid

Leave to a Manual test what an End-to-end test can catch.

RationaleCrash, don't guess

A program that continues past an unexpected state runs on a guess. Jim Shore’s Fail Fast: code that works around errors fails mysteriously later; code that stops at once reveals the defect where it lives. Joe Armstrong’s Erlang thesis: skip the defensive code, let the process die, recover elsewhere. RFC 9413 shows that tolerated faults become permanent contracts.

PrincipleFail fast

A system fails loudly and at once on an unexpected state; it never continues on a guess. A safeguard that swallows a failure is added only where Evidence shows the need.

RuleNo silent catchMUST NOTFailure Handling

Use Try/catch blocks that do not Rethrow (silencing failures).

RuleNo default on failureMUST NOTFailure Handling

Return or use a Default value when failing.

RuleNo strategy fallbackMUST NOTFailure Handling

Make code ‘hardened’ with a Fallback strategy tried when the first one fails.

RuleNo suppressed exit statusMUST NOTFailure Handling

Discard or ignore a failed Exit status, error return value, or faulted operation so that a failure passes as success.

StandardNo || trueBash

|| true and || : after a command.

RuleNo discarded diagnosticsMUST NOTFailure Handling

Send a command’s Error output nowhere, or use another tool to detect state instead of letting the failing tool report its error.

StandardNo 2>/dev/nullBash

2>/dev/null on a command whose failure matters.

RuleScripts abort on errorMUST NOTFailure Handling

Let a script continue past a failing step. Every script runs in the language’s Abort-on-error mode, and a failing step ends it at once.

Standardset -euo pipefailBash

set -euo pipefail as the first statement after the Shebang of every script.

RuleNo degraded continuationMUST NOTFailure Handling

Proceed with stale, partial, or assumed input after the step that produces it failed with a failed Exit status or Exception; report and stop.

RuleLinear deterministic codeMUST NOTFailure Handling

Write test, build, or configuration code that contains Branching logic or fallback Default values, such as, but not limited to, if Statements, switch/case expressions, or defaulted values.

RationaleTranslate at the door

Code We Cannot Control speaks its own dialect, a Foreign shape. Alistair Cockburn’s Hexagonal Architecture and Eric Evans’s Anti-Corruption Layer both put translation at a port, so foreign models never leak inward. Parsed once at the Perimeter into types that cannot hold Illegal states, a value is never checked again. Tony Hoare’s billion-dollar mistake shows the cost of uncertainty travelling through every reference. One adapter per foreign shape keeps upgrades local.

  • SHOULD

    Give every foreign system its own adapter behind a port.

  • SHOULD

    Introduce an anti-corruption layer where the foreign model’s meaning differs from ours (Anti-Corruption Layer).

PrincipleFold at Perimeter

The Foreign shape is folded into an Encapsulated type at the Perimeter and back only there. Inward of that point nothing sees it.

RuleForced optionality at perimeterMUSTContracts

Handle Optionality forced by Code We Cannot Control in the Statement that invokes it or receives its return.

PrincipleParse, don't validate

Parse raw input once, at the Perimeter, through the Validating path of creation, and pass the type on; never check a primitive and pass the primitive on.

RuleValidating factoryMUSTTypes

Provide Instances only through a named Factory that establishes every Invariant before returning.

RulePrivate constructorMUSTTypes

Keep the Constructor private, or unexported from its Module.

RuleCreation failure in the signatureMUSTTypes

Return the invalid-input case from a Factory in its type Signature rather than throw an Exception.

RationaleEncapsulation

An Encapsulated type with one Validating path of creation makes Illegal states unrepresentable. Yaron Minsky’s Effective ML Revisited names the idiom, Make illegal states unrepresentable, and Scott Wlaschin’s Designing with types works it through. Any weaker typing, one that does not fully encapsulate or leaves a second path of creation open, hands the validation back to every caller.

When an API passes int x, int y as coordinates, fold them into a CarPosition, not a Coordinate. A CarPosition is never collapsed into ints again: all our code keeps it as a CarPosition, perhaps uses a generic Position, or converts it into a DriverPosition once it is verified to be moving. In the best case CarPosition stays opaque, the best encapsulation: No code ever knows or depends on the fact that there might be two ints inside. When it is written to the database, at the Perimeter, the database context consumes it as a CarPosition and, by contract, perhaps a visitor, folds it into a database parameter belonging to the CAR_POSITION table. A Domain primitive is the special case where a single primitive is wrapped.

Every typing add-on to a weakly typed language exists to be used for this. Even an environment without types can mint a naming standard in which a variable prefix carries the signature “validated by factory”, and a linter enforcing that standard shifts the validated contract further left.

  • SHOULD

    Use every typing add-on the language offers to give every type one Validating path of creation and no other.

  • SHOULD

    Where code smells of Optionality and Primitive Obsession, improve it first by introducing encapsulation: refactor to opaque types, and retire the tests that only guarded against values the types can no longer hold.

  • MAY

    Where the environment has no types, mint a naming prefix that marks a value validated by its factory, and enforce it with a linter.

  • SHOULD

    Hide a type’s representation outside its defining module, as a new type or a branded type, rather than share it through an alias, so values that share a representation but not a meaning cannot be mixed.

  • SHOULD

    Encode a state machine in the type, each transition consuming the old state’s type and returning the new one, so an operation invalid in the current state does not typecheck.

  • SHOULD

    Enforce a collection’s invariants in its type: a non-empty list makes head and max total, and a first-class collection enforces uniqueness, bounds, and ordering in one place.

  • SHOULD

    Attach predicates to types and have them verified at compile time where the ecosystem provides it: refinement types, units of measure, checked type qualifiers.

  • MAY

    Implement the language’s comparison interface on a Domain object rather than compare its primitives.

PrincipleMake illegal states unrepresentable

Choose the Type system over a Runtime check, and model every business rule, transition, and entity as a dedicated type rather than a data bag. A state that cannot be held needs no validator, no test, and no bug report.

RuleSum typesMUSTTypes

Enumerate the legal alternatives as a closed Sum type rather than a Product type of optional fields.

RuleClosed enumerationsMUSTTypes

Model every legal domain state as a closed enumeration of Encapsulated types with belonging Domain methods and possible transitions.

RuleCompile-time optionalityMUSTTypes

Make absence an explicit case the Compiler forces every caller to handle.

RuleExhaustive matchingMUSTDomain Model

Use Pattern matching over the closed set of cases, with no Wildcard pattern.

RuleSelf-guarding aggregatesMUSTDomain Model

Route every state change of an Aggregate through a Domain method that re-establishes its Invariants.

RuleNo unwrappingMUST NOTDomain Model

Unwrap Domain objects into Primitives anywhere but at the Perimeter.

RuleStrong typingMUST NOTDomain Model

Represent a domain concept with a Loose type.

StandardNo any in domain signaturesTypeScript

any, unknown, object, or Record<string, unknown> in the signature of a Domain object or its operations.

RuleDomain-only interfacesMUSTDomain Model

Access a Domain object only through methods that accept and return Domain objects, the Validating factory at the Perimeter excepted.

RuleDomain operationsMUSTDomain Model

Perform comparison, addition, subtraction, or any other domain operation via Domain methods.

PrincipleImmutable by default

A Domain object is Immutable. A validly constructed object that cannot change cannot become invalid.

RuleNo mutatorsMUST NOTDomain Model

Expose a Setter or any operation that changes a Domain object in place. A change returns a new Instance that passes the Validating path of creation again.

PrincipleNo Primitive Obsession

Any primitive in a method signature is the Primitive Obsession smell: the value it carries deserves a type of its own. The only exception is a method at the Perimeter.

RuleWrap primitivesMUSTTypes

Wrap a Primitive in its Domain primitive before it crosses any Interface of ours.

RuleNo primitive leakageMUSTDomain Model

Keep raw Primitives from crossing a Layer boundary.

RationaleTelemetry over guesswork

A feature that has shipped without a signal is a feature we hope works. The Shift Left axiom does not stop at release: the earliest point at which a production defect can be observed is by us, from telemetry, and the latest is by the customer, from the symptom. The Google SRE book’s Monitoring Distributed Systems reduces what to watch to four golden signals, latency, traffic, errors, and saturation, and pages only on symptoms already affecting users, which is possible only if the Signals were in place before the change was. The Signal therefore ships with the behaviour it shows, not after its first incident, and a regression is found and resolved before the customer notices a flicker. Adding them afterwards is the same shortcut as adding the test afterwards, and is skipped for the same reasons.

  • SHOULD

    Instrument every service for the four golden signals before its first deploy.

  • SHOULD

    Alert on symptoms Users experience, and keep cause-level Signals for diagnosis rather than paging.

PrincipleOwn the Runtime

A behaviour ships with its Signal; if we cannot see it, it is not shipped.

RuleShip with telemetryMUSTToolchain & Environment

Add the Signal in the Change that adds the behaviour it shows.

AxiomWithout Verification It Is Worthless

Without verification it is at best worthless, more often a source of confusion.

When you know a thing, to hold that you know it; and when you do not know a thing, to allow that you do not know it; this is knowledge. Analects II.XVII
RationaleTests prove behaviour, not execution

A line that runs under test is not a line that is checked. Martin Fowler’s AssertionFreeTesting describes suites with full coverage that verified nothing; Inozemtseva and Holmes found coverage predicts little about fault detection once suite size is controlled for. A test that asserts outcomes is an executable specification that documents and guards behaviour on every commit.

  • SHOULD

    Run mutation testing to show that the tests fail when the code is wrong (State of Mutation Testing at Google).

  • SHOULD

    Treat painful test setup as a design signal: split the subject into smaller domain models or focused interfaces before reaching for a mock.

  • SHOULD

    Almost all code has tools for verification, make sure they are used inside the [project].

PrincipleTest-Driven Development

Write a test first.

RuleNo muted testsMUST NOTTests

Leave a Muted test or skip Tests.

RuleAdd tests for new codeMUSTTests

Add Tests for new Production code.

RuleAdd tests for updated codeMUSTTests

Add Tests for updated Production code.

PrincipleNever fix a bug without a test pinning it

A bug is pinned by a failing test before it is fixed, and the fix is done when that test passes.

RuleTroubleshooting unit testMUSTTests

Any bug fix has a Unit test pinning it.

PrincipleNo grey tests

A test is either a black-box test of the shipped artifact or a test of one subject in isolation; nothing in between.

RuleOne subject under testMUST NOTTests

Include more than one Subject under test in a Unit test, Narrow integration test, or Integration test, or test the composition of objects within a Unit test or a Narrow integration test.

RuleIntegration Tests Are Black-BoxMUSTTests

Test the shipped Runtime artifact through its public APIs using Black-box testing.

PrincipleNever trust a test you haven't seen fail

A test counts only once it has failed for the behaviour it checks; a test that cannot fail checks nothing.

RuleNo coverage-only testsMUST NOTTests

Write Tests that discard return values, or make Assertions on generalizations such as the presence or type of the asserted value, just to increase Code coverage.

PrincipleF.I.R.S.T.

Tests are Fast, Independent, Repeatable, Self-validating, and Timely.

RuleAssert valuesMUSTTests

Make an Assertion on the actual returned values — not merely that no error occurred, or on generalizations such as the presence or type of the asserted value.

RuleNo retry on failureMUST NOTTests

Configure a Test to run again until it passes, by a retry count, a retry annotation, or a Flaky test marker.

RuleNo test case couplingMUST NOTTests

Allow one Test case to depend on another; every test case is executable on its own, in any order.

PrincipleVerification ends the chain

All Production code is tested. Verification code is not production code and is not tested.

AxiomQuality Uncompromised

Quality is always the highest priority; it is what makes the other priorities possible.

When you have faults, do not fear to abandon them. Analects I.VIII
RationaleWhat wins when values collide

Each Software quality axis is challenged by a Competing good, and when they collide the axis wins. The pairs read in both directions: finding the competing good in code is a symptom that its axis needs attention, and the repair belongs on the axis, not in more of the good. Quality is not measured by what a competing good offers: Performance and Feature Rich are requirements like any other, and meeting one is part of Correctness, but neither earns credit against the other axes.

ValueExcellence Through Transparency

We hire for talent and grow by collaboration. By staying humble, surfacing blockers early, and sharing what we don’t know, our product becomes the sum of our competence. Transparency is our shortcut to deliver excellence.

Without this we are not truly a team, and the software we deliver does not have the leverage of our combined competence behind it. Sharing what we don’t know is positive: it shows where our code or our Framework needs mending. We don’t brush bugs under the carpet. Bugs are valuable gems; they point out defects in our Quality system and give us the chance to improve.

AxiomCompetence Applied Is Leverage

A tool multiplies the competence applied to it and supplies none of its own; it decides how fast the outcome arrives, never what it is.

A carpenter or a carriage-maker may give a man the circle and square, but cannot make him skilful in the use of them. Mencius VII.II.V
RationaleThe practitioner decides the outcome

AI is leverage applied to a Practitioner (Competence Applied Is Leverage). Applied by someone who does not know what good looks like, it produces a mess at a speed no one could reach unaided, and the mess arrives reviewed, formatted, and entirely plausible. Applied by someone working from these documents, it produces the same Quality faster, and more of it. Lisanne Bainbridge’s Ironies of Automation (1983) names the mechanism: automation takes over the routine and leaves the Practitioner exactly the judgement it could not encode, so the more capable the tool, the more the outcome rests on the person. Two measurements show it from both sides. Generative AI at Work (Brynjolfsson, Li, Raymond, 2023) found the gains concentrated in novices, because the model disseminated the practice of the most able workers: the tool carried competence that already existed. METR’s early-2025 study found experienced Developers 19% slower with AI tools while believing themselves 20% faster: what the tool multiplied there was the confidence, not the result.

The distance between what a person and what a model can do narrows every day, so anything justified by “AI cannot do this yet” carries an expiry date and is not written as permanent. What does not narrow is Fred Brooks’s essential complexity: tools attack the accidental, and knowing which problem is worth solving, what good means here, and whether the result is true stays with the Practitioner. Investment therefore goes to the Practitioner’s competence, and to stating our standard explicitly enough to be applied, over the expectation that a better model compensates for the absence of both.

  • SHOULD

    State a standard in these documents before handing it to a tool to apply, so the tool multiplies a definition and not a habit.

  • SHOULD

    Keep the rules, prompts, harnesses, and pipelines that carry our standard under our own control; a vendor’s default encodes the vendor’s standard, an average of everyone’s practice rather than ours. Everything below that layer is consumed through the Development Stack like any other component.

  • SHOULD

    Verify generated output by the same means as any other change; fluency and confidence are properties of its form and say nothing about its Correctness.

PrincipleAdoption is articulation

Adopting a tool that applies our standard begins by writing the standard down: the rule an AI agent needs is the rule a new colleague needs, and the reason it was never written is that it lived as habit. An adoption that leaves our craft no more clearly stated than before has adopted nothing.

RuleNo unstated standardMUST NOTConventions

Instruct an AI agent to follow a Coding standard that has no entry in these documents; add the entry and cite it.

AxiomCode Is Written for People

Code explains to people what the machine will do.

If names be not correct, language is not in accordance with the truth of things. If language be not in accordance with the truth of things, affairs cannot be carried on to success. Analects XIII.III
RationaleRead far more than written

A line of code is written once and read many times: by the reviewer, by the next Developer, by whoever is on call when it fails. Professionals spend about 58 percent of their working time understanding code (Xia et al., IEEE TSE 2018), and “code is read much more often than it is written” (PEP 8). The reader’s cost decides how code is shaped, and Readability is the first Software quality axis a reader meets.

  • SHOULD

    Shape every unit of code, a file, a type, a function, to be read in one sitting by a reader who has not seen it before.

PrincipleLess is more

A Component is small enough to be read whole, so that a reader unfamiliar with it sees what it does without holding more than one screen in mind.

RuleSingle-purpose componentsMUSTConventions

Decompose Production code into small, single-purpose Components.

RationalePremature optimization and Jackson's rules

What the machine executes is the compiler’s output, not the author’s text. Donald Knuth asked that we stop “imagining that our main task is to instruct a computer what to do” and “concentrate rather on explaining to human beings what we want a computer to do” (Literate Programming, 1984); Abelson and Sussman put it as “programs must be written for people to read, and only incidentally for machines to execute” (SICP, preface). Knuth warned that “we should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%”—and that critical three percent is found by measurement, “only after that code has been identified” (Computing Surveys 1974, p. 268). Michael A. Jackson codified the discipline in two rules (Principles of Program Design, 1975): Rule 1 is “Don’t do it”; Rule 2 (for experts only) is “Don’t do it yet—that is, not until you have a perfectly clear and unoptimized solution.” A clear, well-decomposed architecture is the prerequisite to profiling: you cannot isolate or replace a bottleneck in tangled code.

  • SHOULD

    Measure before optimising, and optimise only the bottleneck the measurement names.

PrincipleMake it work, make it right, make it fast

Deliver working behaviour in small slices first, structure the code clearly for the reader second, and optimise only measured bottlenecks last (Kent Beck); speed is never bought with less readable code.

  • SHOULD

    Reduce scope, split the Pull request into several smaller ones, and ship a working slice.

RuleKeep pull requests smallMUSTPurpose

Keep every Pull request small enough to merge quickly without diverging from the main branch.

RuleMake it work firstMUSTPurpose

Deliver working behaviour for the stated Purpose before refactoring structure or optimising Performance.

RuleNo performance motivations on in-memory operationsMUST NOTPerformance

Motivate any Change by Performance on In-memory operations; a performance change reduces Calls over the network or addresses a bottleneck proven by a named measurement as Evidence.

ValueOutcome Over Output

We value customer collaboration over following a rigid plan. Our job isn’t to check off a requirements list; it’s to solve a problem. We challenge assumptions and connect the dots across architecture and culture to uncover what’s truly needed. We don’t take the “easy” path—we take the path that delivers the most meaningful impact.

AxiomSimplicity

Simple solutions are better than complex ones.

In language it is simply required that it convey the meaning. Analects XV.XL
RationaleCode is a liability, not an asset

Simplicity is the fit between a job and the tools and strategies chosen to do it: a solution is simple when it carries nothing the job does not call for, and complex in proportion to what it carries beyond that. Every line carries the ongoing cost of being read, supported, and updated as the ecosystem around it evolves, and is worth that cost only where it meets a user need (Software Engineering at Google, Why Deprecate?). Edsger Dijkstra: if we count lines of code, “we should not regard them as ‘lines produced’ but as ‘lines spent’” (EWD1036), and Jeff Atwood: “Every new line of code you willingly bring into the world is code that has to be debugged, code that has to be read and understood, code that has to be supported” (The Best Code is No Code At All). Code outside the stated Purpose is not free. Martin Fowler’s Yagni names four costs: building it, delaying real features, carrying its complexity, and repairing it when the guess proves wrong. Ron Jeffries: “the best way to have fewer bugs is to implement less code.” Keeping every part inside the Purpose keeps the codebase small enough to understand and change quickly, and every test and review aimed at what Users need.

  • SHOULD

    State the User need before the change is reviewed, so every part of the change can be traced to it.

  • SHOULD

    Record, for every level of the Development Stack above the one chosen, the search performed and what it found.

  • SHOULD

    Choose the technology the team already operates before adopting a new one.

PrincipleYou aren't gonna need it

Always implement things when you actually need them, never when you just foresee that you need them (Ron Jeffries).

RuleStated purposeMUSTPurpose

State the Purpose of every Change.

RuleNo code without purposeMUST NOTPurpose

Write or merge code whose Purpose is not stated.

RuleNo speculative portabilityMUST NOTPurpose

Add platform, shell, or environment Compatibility branches for Environments the task does not run in.

RuleDelete unusedMUSTDead Code

Delete Tests, Production code, and Helper code that are no longer relevant or used.

PrincipleCode as a Subset of the Purpose

Every part of the code solves some part of its Purpose, and no part reaches outside it. What it solves, it solves accurately and without harm the Users would not accept.

RuleEvery part solves the PurposeMUSTPurpose

Trace every part of the Change to the part of the stated Purpose it solves.

RuleNothing beyond the PurposeMUST NOTPurpose

Solve more than the stated Purpose.

PrincipleChoose boring technology

Keep the Development Stack small and well known: “every company gets about three innovation tokens” (Dan McKinley).

RuleNo platform feature where reuse servesMUST NOTReuse

Meet a need with the Platform or framework when Codebase reuse meets it.

RuleNo dependency where the platform servesMUST NOTReuse

Add an External dependency when the Platform or framework meets the need.

RuleNo external service where a dependency servesMUST NOTReuse

Integrate an External tool or service when an External dependency meets the need.

RuleNo new code where an external tool servesMUST NOTReuse

Write New code when an External tool or service meets the need.

RuleAvailableMUST NOTReuse

Adopt existing code that requires payments or license models, or an extra Platform or framework, that would increase the maintenance burden.

RuleMaintainedMUSTReuse

Adopt existing code only where it is a Maintained library or framework that is stable, documented, and maintained by several active contributors.

RationaleOptionality Drives Complexity

Each optional flag doubles the paths a function can take, and most of them are never tested (Pete Hodgson, Feature Toggles). Martin Fowler’s FlagArgument: a named operation states intent where a bare boolean hides it. Robert Harper’s Boolean Blindness: a flag carries no meaning of its own.

  • SHOULD

    Make the toggle a strategy so that it encodes all options it controls

  • SHOULD

    Make overload or specific behaviour Explicitly named methods instead of optional flags

PrincipleAvoid optionality

Each allowed combination of options is its own operation with its own name; Optionality is never a parameter.

RuleNo optionalityMUST NOTContracts

Use optional variables or Optional parameters unless Code We Cannot Control forces them.

RulePrefer APIs without optionalityMUSTContracts

Choose, among Code We Cannot Control that meets the need, an API without Optional parameters over one with them.

RuleOverload per option combinationMUSTContracts

Provide an Overload or an Explicitly named method for each allowed combination of options instead of Optional parameters.

RationaleAmdahl's Law and the I/O-bound reality

Gene Amdahl’s law (AFIPS 1967) bounds the speedup of any system by the fraction of time spent in the part being improved. In enterprise software, execution time is dominated by I/O—database queries, filesystem access, and Calls over the network taking milliseconds to hundreds of milliseconds—while In-memory operations execute in nanoseconds, representing promilles of the total latency budget. Micro-optimising In-memory operations yields near-zero system return while trading away Readability and Maintainability; real Performance gains come from eliminating redundant I/O and batching Calls over the network.

PrincipleIterations over calls over the network is bad design

Iterations over Calls over the network is bad design.

RuleNo iteration over calls over the networkMUST NOTPerformance

Iterate over Calls over the network.

AxiomGreat Products Require Users

Code proves execution; Users prove Correctness.

He acts before he speaks, and afterwards speaks according to his actions. Analects II.XIII
ValueJoy Through Craft

We founded this company on a simple realization: working by these values is, quite simply, the most fun. We believe that doing things the right way—with discipline, transparency, and Purpose—is the most rewarding way to spend our time. For us, “fun” isn’t a distraction from the work; it is the byproduct of mastering our craft and building Great software that we’re proud of. We didn’t just build a company to solve a problem; we built it to enjoy the journey together.

Repetition leads to boredom; any form of repetition is, for us, a challenge to automate. Adopting bleeding-edge technology correctly gives us technical supremacy, and we use that supremacy to conquer the next level of Automation. Technology advances relentlessly, and we are fast to respond and embrace change. Staying current is constant elevation. Hunting boredom with bleeding-edge technology is our craft and our joy.

AxiomEasy to Change

Great software stays great when it is easy to maintain and extend.

To have faults and not to reform them, this, indeed, should be pronounced having faults. Analects XV.XXIX
RationaleRobustness Principle

Be conservative in what you send and liberal in what you accept (RFC 1122 § 1.2.2, Postel’s law). A producer emits exactly the shape it defines; a consumer takes what it needs from what it receives and is not disturbed by what it does not know.

This includes Martin Fowler’s Tolerant Reader: with one producer and many consumers, the producer is the single source of the shape and moves first, its consumers catch up at their own pace, and nothing breaks in between. Gating the producer on the slowest consumer is the unmaintainable order.

  • SHOULD

    Ship the expanded contract, migrate its consumers, then remove what is left over, so every step deploys on its own (Danilo Sato, Parallel Change).

  • MAY

    Let consumers publish the parts of the contract they rely on, so the producer sees what a change would break before it ships (Ian Robinson, Consumer-Driven Contracts).

PrinciplePrepare reader for evolving producer

Every reader accepts changes it does not know, so the producer evolves without updating every reader first.

RuleAccept unknown propertiesMUSTContracts

Accept a Foreign shape that carries properties you do not know, and ignore them.

StandardadditionalProperties never falseJSON Schema

additionalProperties is never false.

StandardunevaluatedProperties never falseJSON Schema

unevaluatedProperties is never false.

RuleGeneric parameters, specific returnsMUSTContracts

Declare the most generic Parameter types and the most specific Return type a Public method can honour.

RationaleOne concern, one owner

Edsger Dijkstra named separation of concerns the only reliable way to order one’s thoughts (EWD447); David Parnas made it structural: each module hides one decision likely to change. When a behaviour has one owner in one layer, changing it touches one place and one set of tests. Scattering it saves minutes today and costs a hunt, and a missed copy, on every future change.

  • SHOULD

    Hide each design decision likely to change behind one module interface.

  • SHOULD

    Keep configuration out of the code and read it from the environment (The Twelve-Factor App, III. Config).

  • SHOULD

    Keep concerns separate where merging them would save lines; the lines saved are paid back on every later change.

PrincipleSeparation of Concerns

Each concern has one owner in one layer, and a change to a behaviour touches only its owner.

RuleRespect layeringMUST NOTDomain Model

Import or call against the Dependency direction the architecture declares: from a Layer into the layer above it, or skipping a layer.

StandardLayer dependencies as an ArchUnit testArchUnit

A layered-architecture test that declares each layer and the layers it may depend on, failing the build on any other dependency.

RuleDomain separated from transport and frameworkMUSTDomain Model

Isolate Domain object representations in their own Module separated from transport Foreign shapes and Framework code, with no dependencies on other Modules in the project, using Interface abstractions that hide concerns of technical character.

RationalePolymorphism over conditionals

Repeated if/else or switch Branching logic scatters knowledge of variants across every caller: adding a variant means hunting down and editing every conditional. Bertrand Meyer’s Open/Closed Principle resolves this by keeping modules open for extension and closed for modification—new behaviour arrives as a new implementation of an Interface, not a new branch in existing callers. Craig Larman’s GRASP Polymorphism and Martin Fowler’s Replace Conditional with Polymorphism assign the varying behaviour to the type for which it varies, while Tell, Don’t Ask keeps callers from querying a Domain object’s state to decide on its behalf. Decisions about which variant to run, which Feature to wire, or how to assemble optional parts belong once at the Perimeter—inside a Factory, Feature, or Builder—so core domain and application logic executes linearly through polymorphic contracts.

PrincipleReplace conditional with polymorphism

Resolve variant selection and optional assembly once at the Perimeter through a Factory, Feature, or Builder, and execute domain and application logic through polymorphic Domain objects without conditional Branching logic.

RuleBranching belongs at the perimeterMUSTDomain Model

Use a Factory with Inheritance, a Feature, a Strategy, or a Builder instead of a boolean or Pure enum.

RuleTell, don't askMUST NOTDomain Model

Query a Domain object’s state to decide how to act upon it instead of invoking a Domain method on it.

From Rules to Values

Every rule, followed up its parent chain to the value it serves.

Index

Every entry of every level, linking into the tree. An entry whose parent chain is broken has no place in the tree, and its link here fails the build.

Values

Axioms

Rationales

Principles

Rules

Standards

Glossary

Marker

The RFC 2119 priority word that opens a rule or a solution.

Exactly these kinds: MUSTMUST NOTSHOULDSHOULD NOTMAY.

Kinds known so far: .

MUST

An absolute requirement.

Exactly these kinds: .

Kinds known so far: .

MUST NOT

An absolute prohibition.

Exactly these kinds: .

Kinds known so far: .

SHOULD

A requirement that may be set aside only with a stated, valid reason.

Exactly these kinds: .

Kinds known so far: .

SHOULD NOT

A prohibition that may be set aside only with a stated, valid reason.

Exactly these kinds: .

Kinds known so far: .

MAY

An option.

Exactly these kinds: .

Kinds known so far: .

Defined

Exists as an entry in this glossary.

Exactly these kinds: .

Kinds known so far: .

Id

The name of an entry, and the only stable handle for citing it. Ids are unique across every document, compared case-insensitively with whitespace normalized. In prose an id is cited as Id.

Exactly these kinds: .

Kinds known so far: .

Group

The topical cluster a rule belongs to, taken from the heading the rule sat under. It orders and clusters rules for readers and has no bearing on precedence.

Exactly these kinds: .

Kinds known so far: .

Parent

The id of the entry directly above. Every entry below the root has exactly one parent.

Exactly these kinds: .

Kinds known so far: .

Purpose

The stated reason something is built or changed, expressed as the benefit it delivers to Users.

Exactly these kinds: .

Kinds known so far: .

Users

Whoever consumes the software or system to fulfill a need. A Developer is not a user.

Exactly these kinds: .

Kinds known so far: End userOperatorExternal systemAI agent.

End user

A person who uses the product to meet their own need.

Exactly these kinds: .

Kinds known so far: .

Operator

A person who keeps the system running in production.

Exactly these kinds: .

Kinds known so far: .

External system

A system outside the current code base that calls it or is called by it.

Exactly these kinds: .

Kinds known so far: .

AI agent

A program that pursues a goal autonomously, using a model to decide its next action.

Exactly these kinds: .

Kinds known so far: .

Developer

Whoever writes, reviews, or maintains the code: a person or an AI agent. Every rule is applied by a developer, on a diff, and holds the same for either kind. A developer is not a User.

Exactly these kinds: .

Kinds known so far: .

Component

A Class or any larger unit of code—such as a file, folder, module, package, or project—with its own Interface and namespace that decides which of its parts are visible outside it.

Exactly these kinds: .

Kinds known so far: .

Class

A construct that defines a type as a set of values together with the operations on them. A rule that names a Class applies to every construct that does this, whatever the language calls it.

Exactly these kinds: .

Kinds known so far: .

File

Alias for Component.

Exactly these kinds: .

Kinds known so far: .

Function

A callable unit of code that takes zero or more parameters and returns a result.

Exactly these kinds: .

Kinds known so far: .

Interface

The boundary through which code outside a Component invokes it.

Exactly these kinds: .

Kinds known so far: .

Public method

A single invocation receiver of an Interface: one operation that code outside the Component can invoke through it. An operation that only code inside the Component can invoke is not a public method.

Exactly these kinds: .

Kinds known so far: .

Domain object

A type in the domain layer that models a business concept and upholds its own invariants: Immutable, created only through its Validating path of creation, and operated on only through other domain objects.

Exactly these kinds: .

Kinds known so far: .

Encapsulated type

A Class into which one or more Primitives are folded at the Perimeter, named for what the values mean rather than for their shape, with a single Validating path of creation, and Immutable. Inside our code it is never collapsed back into Primitives; it becomes another type only through a verified conversion, and at an outbound Perimeter a contract of the type folds it into the Foreign shape. Kept opaque, no code depends on its internal representation.

Exactly these kinds: .

Kinds known so far: Domain primitive.

Domain primitive

The special case where a single Primitive is wrapped.

Exactly these kinds: .

Kinds known so far: .

Loose type

The shape of a variable, defined so loosely that it admits Illegal states by design, the opposite of Make illegal states unrepresentable. Its looseness shows in the type’s cardinality, which every field and every open choice multiplies while the legal states stay few.

Exactly these kinds: .

Kinds known so far: OptionalityPrimitive ObsessionMutator.

Primitive Obsession

Representing a value by one or more Primitives instead of a type of its own, leaving its meaning and constraints to every piece of code that handles it.

Exactly these kinds: .

Kinds known so far: .

Optionality

A choice left open in a value or parameter, such as whether it is present at all.

Exactly these kinds: .

Kinds known so far: .

Setter

An operation that assigns a new value to a field of an existing object, a second path of creation that skips the validation of the first. A strong code smell.

Exactly these kinds: .

Kinds known so far: .

Immutable

Unable to change after creation. A change produces a new value, which passes the same Validating path of creation as the first. Without it, a factory’s validation holds only for the moment of creation.

Exactly these kinds: .

Kinds known so far: .

Code We Cannot Control

Code that is not part of the current code base and whose shape we cannot change.

Exactly these kinds: .

Kinds known so far: FrameworkLibraryExternal systemUser input.

Framework

Code outside the current code base that calls our code and owns the flow of control.

Exactly these kinds: .

Kinds known so far: .

Library

Code outside the current code base that our code calls, leaving the flow of control with our code.

Exactly these kinds: .

Kinds known so far: .

User input

Data a person enters through a user interface.

Exactly these kinds: .

Kinds known so far: .

Perimeter

A point in our code that either invokes, or is invoked by, Code We Cannot Control.

Exactly these kinds: .

Kinds known so far: .

Illegal state

A combination of values that the domain never defined as valid.

Exactly these kinds: .

Kinds known so far: .

Development Stack

The ways to meet a need, in order of how little code we own afterwards.

Exactly these kinds: No codeCodebase reusePlatform or frameworkExternal dependencyExternal tool or serviceNew code.

Kinds known so far: .

No code

Meeting the need without any code.

Exactly these kinds: .

Kinds known so far: .

Codebase reuse

Meeting the need with code already in this codebase, refactored into a reusable Component where it is not one yet.

Exactly these kinds: .

Kinds known so far: .

Platform or framework

Meeting the need with what the platform or Framework in use already provides.

Exactly these kinds: .

Kinds known so far: .

External dependency

Meeting the need by adding an existing external Component as a dependency.

Exactly these kinds: .

Kinds known so far: .

External tool or service

Meeting the need by integrating an existing external tool or calling an existing service.

Exactly these kinds: .

Kinds known so far: .

New code

Meeting the need by writing new code.

Exactly these kinds: .

Kinds known so far: .

Test Pyramid

The places a defect can be caught, from the base, earliest and cheapest, to the top, latest and costliest.

Exactly these kinds: Type systemStatic code analysisUnit testNarrow integration testIntegration testEnd-to-end testManual test.

Kinds known so far: .

Type system

Preventing a defect by choosing a type in which the Illegal state cannot be constructed.

Exactly these kinds: .

Kinds known so far: .

Static code analysis

Catching a defect by analysing the code before it runs, with a linter or another static tool.

Exactly these kinds: .

Kinds known so far: .

Unit test

Catching a defect by exercising one Subject under test in-process, without an External dependency.

Exactly these kinds: .

Kinds known so far: .

Narrow integration test

A Unit test without the in-process requirement: one Subject under test exercised against a real instance of the External dependency it talks to, such as a repository against a database in a container (Martin Fowler, IntegrationTest).

Exactly these kinds: .

Kinds known so far: .

Integration test

A Test of one Subject under test—the shipped Runtime artifact—running and tested through its public APIs using Black-box testing, with External dependency instances emulated via their official containers, or second-best containers as production-like as possible.

Exactly these kinds: .

Kinds known so far: .

End-to-end test

Catching a defect by exercising fully deployed services in a running staging environment.

Exactly these kinds: .

Kinds known so far: .

Manual test

Catching a defect by a person exercising the running system.

Exactly these kinds: .

Kinds known so far: .

Evidence

A verifiable reference that grounds a change or an assumption. A practice recalled from experience is not evidence.

Exactly these kinds: Code referenceTest referenceDocument reference.

Kinds known so far: .

Code reference

A full URL to code on the main branch of an existing or public repository.

Exactly these kinds: .

Kinds known so far: .

Test reference

A test in an existing repository.

Exactly these kinds: .

Kinds known so far: .

Document reference

A full URL to a specific section of an article or document.

Exactly these kinds: .

Kinds known so far: .

Demonstrable standard

A standard that can be pointed at. A habit recalled from past experience, or a practice whose community has moved on, is not a demonstrable standard.

Exactly these kinds: Published conventionMaintained library or frameworkCommunity pattern.

Kinds known so far: .

Published convention

A convention that is written down and published.

Exactly these kinds: .

Kinds known so far: .

Maintained library or framework

A Library or Framework that is actively maintained.

Exactly these kinds: .

Kinds known so far: .

Community pattern

A pattern in current use by a large, active community.

Exactly these kinds: .

Kinds known so far: .

Machine-read comment

A comment that something other than a human reader requires.

Exactly these kinds: ShebangMachine-read directivePublished API documentationMandated license headerGenerated-file banner.

Kinds known so far: .

Shebang

The first line of a script, naming the interpreter that runs it.

Exactly these kinds: .

Kinds known so far: .

Machine-read directive

A directive to a tool that is syntactically a comment.

Exactly these kinds: .

Kinds known so far: .

Published API documentation

Documentation of an Interface that a tool extracts to a published documentation site.

Exactly these kinds: .

Kinds known so far: .

Mandated license header

A license notice that a license or policy requires at the top of a file.

Exactly these kinds: .

Kinds known so far: .

Generated-file banner

A notice marking a file as generated by a tool.

Exactly these kinds: .

Kinds known so far: .

Great Code

Code that avoids becoming a System Failed State.

Exactly these kinds: .

Kinds known so far: .

Great software

Alias for Great Code.

Exactly these kinds: .

Kinds known so far: .

Bad Code

Code that drives the system toward a System Failed State.

Exactly these kinds: .

Kinds known so far: .

Accuracy

Alias for Correctness.

Exactly these kinds: .

Kinds known so far: .

Inaccurate

The state where the system diverges from what Users need, failing to fulfill their intended outcome.

Exactly these kinds: .

Kinds known so far: .

System Decay

The progressive transition of a software system from a healthy state into one or more System Failed States, caused by the accumulation of Bad Code.

Exactly these kinds: .

Kinds known so far: .

System Failed State

A non-operational state the software transitions into when Bad Code accumulates.

Exactly these kinds: .

Kinds known so far: Velocity StagnationRegression CascadesKnowledge DissipationDeployment ParalysisValue Failure.

Velocity Stagnation

The codebase has become so complex or fragile that the team can no longer deliver value at a sustainable pace.

Exactly these kinds: .

Kinds known so far: .

Regression Cascades

Fixing one bug consistently introduces new, unrelated bugs elsewhere in the application.

Exactly these kinds: .

Kinds known so far: .

Knowledge Dissipation

The codebase still runs, but no active team member understands how or why its core logic works.

Exactly these kinds: .

Kinds known so far: .

Deployment Paralysis

Code changes are complete, but the system cannot be safely or reliably shipped to production.

Exactly these kinds: .

Kinds known so far: .

Value Failure

The system has become Inaccurate, failing to do what Users need.

Exactly these kinds: .

Kinds known so far: .

Architectural Direction

The fold of every ADR, read from the highest-numbered downward: a later ADR supersedes an earlier one, so where ADRs are ambiguous or conflict, the first read holds. ADRs are immutable; a change is a new ADR, never an edit, because the history explains why decisions were made and why the project is designed the way it is. The Architectural Direction governs where the project is heading; it does not describe its current state.

Exactly these kinds: .

Kinds known so far: .

Software quality axis

One of ten dimensions defining software quality.

Exactly these kinds: CorrectnessMaintainabilityReadabilityTestabilityStructural simplicityTrue Test CoverageEase of Doing the Right ThingGuardrails Against Doing the Wrong ThingAutomationCurrency of Tools and Libraries.

Kinds known so far: .

Correctness

The degree to which software accurately delivers what Users need.

Exactly these kinds: .

Kinds known so far: .

Maintainability

The property that changing a behavior requires understanding and touching only the component that owns it.

Exactly these kinds: .

Kinds known so far: .

Readability

The property that a reader unfamiliar with the code understands what it does and why without asking the author.

Exactly these kinds: .

Kinds known so far: .

Testability

The property that behavior is exercised in isolation without standing up networks, clocks, or global state.

Exactly these kinds: .

Kinds known so far: .

Structural simplicity

Simplicity as it shows in the design: the property that the design carries no structure that a present requirement does not demand.

Exactly these kinds: .

Kinds known so far: .

True Test Coverage

The property that tests fail when behavior breaks, rather than merely executing code paths.

Exactly these kinds: .

Kinds known so far: .

Ease of Doing the Right Thing

The property that the correct approach is the Path of least resistance for the next contributor.

Exactly these kinds: .

Kinds known so far: .

Guardrails Against Doing the Wrong Thing

The property that types, tests, and tooling cause incorrect approaches to fail early at compile time rather than relying on human vigilance.

Exactly these kinds: .

Kinds known so far: .

Automation

The property that the path between a change and its verified deployment runs without manual intervention.

Exactly these kinds: .

Kinds known so far: .

Currency of Tools and Libraries

The property that dependencies are current and easily kept that way.

Exactly these kinds: .

Kinds known so far: .

Comment intent

A reason prose is written as a comment in code. Every comment intent is replaced by a durable, verifiable mechanism, leaving only Machine-read comments exempt.

Exactly these kinds: ClarificationProcrastinationArchitectural decisionUsage guidanceApology or confession.

Kinds known so far: .

Clarification

Explaining intent in code, replaced by intent-revealing variable names, focused functions, or negative tests.

Exactly these kinds: .

Kinds known so far: .

Procrastination

Deferring work via a TODO, replaced by a Failing test pinning the weakness, smaller production-ready changes, or an explicit plan document.

Exactly these kinds: .

Kinds known so far: .

Architectural decision

Recording a design choice, replaced by an Architectural Direction record under docs/adrs/.

Exactly these kinds: .

Kinds known so far: .

Usage guidance

Explaining how to use code, replaced by user documentation or a README.

Exactly these kinds: .

Kinds known so far: .

Apology or confession

Apologizing for or confessing weak code, replaced by fixing the underlying design flaw or pinning the limitation with a Failing test.

Exactly these kinds: .

Kinds known so far: .

User

Alias for Users.

Exactly these kinds: .

Kinds known so far: .

Quality

Alias for Software quality axis.

Exactly these kinds: .

Kinds known so far: .

Domain objects

Alias for Domain object.

Exactly these kinds: .

Kinds known so far: .

Validating path of creation

The single path through which an Encapsulated type or Domain primitive is constructed at the Perimeter, running all required checks before a value is minted. Holding a value of the type is proof it was checked.

Exactly these kinds: .

Kinds known so far: .

Path of least resistance

The design property where the easiest and most convenient option for a contributor is also the correct one.

Exactly these kinds: .

Kinds known so far: .

Illegal states

Alias for Illegal state.

Exactly these kinds: .

Kinds known so far: .

Failing test

A test that exercises a capability or defect and fails until the correct behavior is implemented.

Exactly these kinds: .

Kinds known so far: .

Production code

Code that executes in a deployment runtime after the build and serves Users.

Exactly these kinds: .

Kinds known so far: .

Verification code

Code that verifies Production code.

Exactly these kinds: .

Kinds known so far: .

Explicitly named method

A method whose name states the specific domain action or concept it performs rather than using generic control knobs or boolean flags.

Exactly these kinds: .

Kinds known so far: .

Mutator

Alias for Setter.

Exactly these kinds: .

Kinds known so far: .

Developers

Alias for Developer.

Exactly these kinds: .

Kinds known so far: .

Practitioner

A human Developer in the act of applying a tool, method, or standard, and whose competence the tool multiplies. Not an Operator, who keeps the system running, and not a User, who consumes it.

Exactly these kinds: .

Kinds known so far: .

Signal

A log line, metric, or alert that shows a behaviour working in production.

Exactly these kinds: .

Kinds known so far: .

Runtime check

A check on a value while the program runs, for a condition a type or a Static code analysis could have rejected before it ran.

Exactly these kinds: .

Kinds known so far: .

Foreign shape

The form in which Code We Cannot Control represents a value.

Exactly these kinds: .

Kinds known so far: .

Surrounding code

The code a change sits among. Its conventions decide what no Demonstrable standard decides.

Exactly these kinds: .

Kinds known so far: .

Competing good

A good commonly offered in exchange for a Software quality axis, which loses to the axis when the two collide.

Exactly these kinds: Feature RichPerformanceWell documentedUser FriendlyIndustry StandardMeasured Coverage.

Kinds known so far: .

Feature Rich

Many capabilities in one system or dependency. Challenges Correctness and Currency of Tools and Libraries.

Exactly these kinds: .

Kinds known so far: .

Performance

A system that is perceived as fast by Users. Challenges Maintainability.

Exactly these kinds: .

Kinds known so far: .

Well documented

Human-readable artifacts that quickly explain the system to Developers. Challenges Readability, Automation, and Guardrails Against Doing the Wrong Thing.

Exactly these kinds: .

Kinds known so far: .

User Friendly

A system a person operates through its interface with little effort. Challenges Testability.

Exactly these kinds: .

Kinds known so far: .

Industry Standard

A Community pattern adopted for its popularity rather than for the need at hand. Challenges Structural simplicity.

Exactly these kinds: .

Kinds known so far: .

Measured Coverage

Code coverage treated as a target: a measure of execution, not of checking. Challenges True Test Coverage.

Exactly these kinds: .

Kinds known so far: .

Change

A set of edits to the code base proposed or merged as one unit, such as a commit or a Pull request.

Exactly these kinds: .

Kinds known so far: .

Pull request

A proposed Change submitted for review before merging into the main branch.

Exactly these kinds: .

Kinds known so far: .

Compatibility branch

A conditional path that runs only on a particular platform, shell, or Environment.

Exactly these kinds: .

Kinds known so far: .

Dependency

Alias for External dependency.

Exactly these kinds: .

Kinds known so far: .

Representation

One place where a piece of knowledge is written down: in code, configuration, schema, or documentation.

Exactly these kinds: .

Kinds known so far: .

Instance

One concrete value of a type, created from it.

Exactly these kinds: .

Kinds known so far: .

Factory

A named function that creates instances of a type and returns invalid input as a value in its signature. A constructor cannot: it can only throw.

Exactly these kinds: .

Kinds known so far: .

Invariant

A condition that holds for every instance of a type, from creation onward.

Exactly these kinds: .

Kinds known so far: .

Constructor

The operation a language runs to create and initialise a new instance of a type.

Exactly these kinds: .

Kinds known so far: .

Module

A Component that forms a namespace and, where the language supports it, a compile-time dependency boundary—such as a project or assembly in C#, a package in Go, a crate in Rust, or a module in Java or TypeScript—that decides which of its parts are visible outside it and which other modules it may reference.

Exactly these kinds: .

Kinds known so far: .

Signature

The declared parameter types and return type of a function or method.

Exactly these kinds: .

Kinds known so far: .

Exception

A signal that interrupts normal control flow to report a failure, unwinding the stack until something catches it.

Exactly these kinds: .

Kinds known so far: .

Sum type

A type whose value is exactly one of a fixed set of alternatives, each possibly carrying its own data.

Exactly these kinds: .

Kinds known so far: .

Product type

A type whose value holds one of each of its fields at once, such as a record, struct, or tuple.

Exactly these kinds: .

Kinds known so far: .

Enum

A type with a fixed, named set of values.

Exactly these kinds: .

Kinds known so far: .

Pure enum

An Enum that carries only labels or scalar values without Domain methods of its own, forcing callers to use Branching on its cases.

Exactly these kinds: .

Kinds known so far: .

Inheritance

Defining specialised subtypes that fulfil a shared base type or Interface so each subtype supplies its own behaviour.

Exactly these kinds: .

Kinds known so far: .

Strategy

An object that encapsulates one interchangeable behaviour behind a shared Interface so callers invoke the Interface without Branching.

Exactly these kinds: .

Kinds known so far: .

Compiler

A program that translates source code into another form and rejects code that breaks the language’s rules.

Exactly these kinds: .

Kinds known so far: .

Pattern matching

Selecting code to run by the shape of a value, with one branch per case.

Exactly these kinds: .

Kinds known so far: .

Wildcard pattern

A pattern that matches any value, used as a catch-all case.

Exactly these kinds: .

Kinds known so far: .

Aggregate

A cluster of domain objects treated as one unit for changes, entered only through its root, which keeps the cluster’s invariants.

Exactly these kinds: .

Kinds known so far: .

Domain method

An operation defined on a domain type that expresses a business action in the domain’s own terms.

Exactly these kinds: .

Kinds known so far: .

Raw collection

A plain list, set, or map exposed directly, so callers can change it without going through its owner.

Exactly these kinds: .

Kinds known so far: .

Primitive

A type—or a value of such a type—with no bounded context. All language literals and built-in scalars (such as integers, strings, or booleans) automatically fall into this category, along with general-purpose value types (such as Money, Date, or Span) that carry no domain-specific Invariants.

Exactly these kinds: .

Kinds known so far: .

Layer

A horizontal slice of an architecture that groups code with the same responsibility and depends only in one declared direction.

Exactly these kinds: .

Kinds known so far: .

Dependency direction

The direction in which one layer or module may depend on another, as the architecture declares it.

Exactly these kinds: .

Kinds known so far: .

Helper code

Small supporting code that exists to serve other code rather than a user-facing behaviour.

Exactly these kinds: .

Kinds known so far: .

Try/catch block

A language construct that runs a block and, if it raises an exception, hands control to a handler.

Exactly these kinds: .

Kinds known so far: .

Rethrow

Raising an exception again from its handler, so it keeps travelling up instead of being swallowed.

Exactly these kinds: .

Kinds known so far: .

Default value

A value used when no other is given, or when obtaining the real one failed.

Exactly these kinds: .

Kinds known so far: .

Fallback strategy

A second way of doing the same work, tried when the first one fails.

Exactly these kinds: .

Kinds known so far: .

Exit status

The outcome returned by a process, command, or operation indicating whether it succeeded or failed, such as a process exit code, an error return value, or a faulted task.

Exactly these kinds: .

Kinds known so far: .

Error output

The separate output stream a program writes its error messages and diagnostics to.

Exactly these kinds: .

Kinds known so far: .

Abort-on-error mode

A setting in which a script stops at the first command that fails, such as set -e in Bash.

Exactly these kinds: .

Kinds known so far: .

Branching logic

Code that chooses between paths at run time, such as if, switch, or a default in a lookup.

Exactly these kinds: .

Kinds known so far: .

Branching

Alias for Branching logic.

Exactly these kinds: .

Kinds known so far: .

Test

Code that runs a piece of the system and checks that it behaves as specified.

Exactly these kinds: .

Kinds known so far: .

Test case

One scenario within a test suite: a setup, an action, and the expected outcome.

Exactly these kinds: .

Kinds known so far: .

Muted test

A test that is present but switched off, so it no longer runs or no longer fails the build.

Exactly these kinds: .

Kinds known so far: .

Code coverage

The share of the code that is executed while the tests run.

Exactly these kinds: .

Kinds known so far: .

Assertion

A statement in a test that compares an actual result with the expected one and fails the test when they differ.

Exactly these kinds: .

Kinds known so far: .

Flaky test

A test that passes and fails on the same code without any change.

Exactly these kinds: .

Kinds known so far: .

Subject under test

The one Component a Test exercises and whose behaviour it checks.

Exactly these kinds: .

Kinds known so far: .

Runtime artifact

The built output that is deployed and run, such as a container image, package, or binary.

Exactly these kinds: .

Kinds known so far: .

Black-box testing

Testing through the public Interface only, without depending on the internals.

Exactly these kinds: .

Kinds known so far: .

Test setup

The code that brings the system into the state a Test needs before the action runs.

Exactly these kinds: .

Kinds known so far: .

Lint rule

One check a linter performs on the code, reporting each place that breaks it.

Exactly these kinds: .

Kinds known so far: .

Pragma

A directive to a Compiler or tool, written in the code, that changes how it treats that code.

Exactly these kinds: .

Kinds known so far: .

Generated code

Code written by a tool from some other source, rather than by a person.

Exactly these kinds: .

Kinds known so far: .

Preset

A named set of Lint rules and settings shared by many projects, used as a starting configuration.

Exactly these kinds: .

Kinds known so far: .

Optional parameter

A parameter a caller may leave out, in which case a Default value is used.

Exactly these kinds: .

Kinds known so far: .

Overload

One of several methods with the same name that differ in their Parameter types.

Exactly these kinds: .

Kinds known so far: .

API

Alias for Interface.

Exactly these kinds: .

Kinds known so far: .

Statement

The smallest unit of code that performs an action, such as an assignment, a call, or a return.

Exactly these kinds: .

Kinds known so far: .

Return type

The declared type of what a Function returns.

Exactly these kinds: .

Kinds known so far: .

Parameter type

The declared type of what a Function accepts in one of its parameters.

Exactly these kinds: .

Kinds known so far: .

Feature

A cohesive user-facing capability or vertical slice of behaviour isolated in its own Component.

Exactly these kinds: .

Kinds known so far: .

Feature toggle

A conditional switch that enables or disables a Feature at run time without deploying new code.

Exactly these kinds: .

Kinds known so far: .

Builder

A construct that assembles a valid, Immutable Domain object step by step instead of taking Optional parameters or Branching logic.

Exactly these kinds: .

Kinds known so far: .

In-memory operation

Computation that executes entirely within process memory without Calls over the network.

Exactly these kinds: .

Kinds known so far: .

Contract

A specification, separate from the code, of what crosses a boundary and what each side must provide.

Exactly these kinds: .

Kinds known so far: .

Coding standard

A set of rules for how code is written in a team, so all of it reads as if one person wrote it.

Exactly these kinds: .

Kinds known so far: .

Environment

A place where the system runs with its own configuration and infrastructure, such as local, test, or production.

Exactly these kinds: .

Kinds known so far: .

Calls over the network

Invocations that traverse a network boundary to communicate with another service, database, or process.

Exactly these kinds: .

Kinds known so far: Access to filesystemAccess to databaseAccess to HTTP.

Call over the network

Alias for Calls over the network.

Exactly these kinds: .

Kinds known so far: .

Access to filesystem

Accessing a local or remote file system.

Exactly these kinds: .

Kinds known so far: .

Access to database

Accessing a relational, document, or key-value database.

Exactly these kinds: .

Kinds known so far: .

Access to HTTP

Accessing an HTTP or HTTPS endpoint.

Exactly these kinds: .

Kinds known so far: .

Head commit

The commit a review of a Change is anchored to. Every file read and every inline comment resolves against it.

Exactly these kinds: .

Kinds known so far: .

Checkout

The Head commit checked out with a clean working tree. A checkout at any other commit is not a checkout of the Change.

Exactly these kinds: .

Kinds known so far: .

Surface

The code a Violation may be reported against, identified by file and line numbers on the left (base) and right (head): changes carrying an unresolved comment, changes carrying a comment the author has resolved since the prior review, and changes new since the prior review (on a first review, the whole Change).

Exactly these kinds: .

Kinds known so far: .

Full context

The Surface together with every changed file in full, the call sites of changed public symbols, and the covering Verification code. Context is what a Verdict is reached from, never what a Violation is reported against.

Exactly these kinds: .

Kinds known so far: .

Ruleset

A subset or grouping of Rules evaluated together as a unit.

Exactly these kinds: .

Kinds known so far: .

Violation

A finding that code on the Surface breaks a Rule.

Exactly these kinds: .

Kinds known so far: .

Verdict

The result of evaluating against a Rule or Ruleset: Violation or non-violation.

Exactly these kinds: .

Kinds known so far: .

Ledger

The list across the sum of Rulesets providing reassurance that every Rule was reviewed: one row per Rule, recording Evidence of what was examined and whether Violations were found or not found.

Exactly these kinds: .

Kinds known so far: .

Schemas

Every governance document is validated against one of these JSON Schemas. Each schema is published at its own $id.