Week 13. Prerequisite: Modules 1–8 and Part 0, §0.7.
9.0 Module map and objectives
Modules 1–8 built a harness that acts. This module addresses a different question: how does a codebase stay legible and correct as agents modify it repeatedly? An agent that can edit a repository is a new kind of contributor: fast, tireless, and capable of introducing the same class of defect many times without learning. A harness that does not constrain what the agent can do, and does not manage the drift that accumulates from many small changes, will degrade the codebase even when every individual change is locally plausible.
The module has four parts and one lab.
| Part | Content | Lab |
|---|---|---|
| A (§9.1–9.4) | The three-part decomposition (context engineering, architectural constraints, entropy management): definition, provenance, evidence status, and how to test it | — |
| B (§9.5–9.12) | Guides vs sensors: the control-theoretic reading, the formal model, the internal model principle, and the optimal allocation | — |
| C (§9.13–9.18) | CI as ground truth; mutation testing as an agent-robustness probe; codebase legibility for agents | — |
| D (§9.19–9.24) | Measuring delivery impact: DORA-style baselines, the stability margin of a change, and the Goodhart risk | — |
| Lab 9 (§9.25) | Retrofit a repository with a constraint layer; A/B test whether defect escape rate falls; report the stability margin | Lab 9 |
By the end of the module you will be able to do eight things:
- State the three-part decomposition and its evidence status (tier B/C, a single organisation’s experience), and design an experiment to test it.
- Classify every harness constraint as a guide (feedforward) or a sensor (feedback), and explain why a balanced design needs both.
- Formalise the guide/sensor allocation as an optimisation over violation rates, and solve it for a stated cost function.
- State and apply the internal model principle to bound the fraction of failures a harness can detect.
- Use CI as the repository’s ground-truth verifier, and explain why a harness without CI has no feedback.
- Measure a test suite’s strength with mutation testing, and interpret the mutation score as a TPR on the mutation distribution.
- Define codebase legibility for agents and measure it.
- Apply DORA-style baselines to a before/after comparison, and compute the stability margin of a change.
Everything is self-contained. Where Part 0 is used, the result is restated in the form needed.
PART A — THE THREE-PART DECOMPOSITION
9.1 The decomposition
9.1.1 What it says
OpenAI’s three-part decomposition, as reported in secondary sources (evidence tier B/C: a vendor’s experience, reported second-hand; treat as a hypothesis, not a finding), describes a coding harness’s work as three activities:
1. Context engineering. Deciding what the model sees: the task, the repository context, the tool schemas, the history. (This is Modules 3, 8.)
2. Architectural constraints enforced by linters and agents. Constraining what the model can produce: linters that reject non-conforming code, type checkers that reject ill-typed code, structural rules that reject disallowed patterns, and agents that enforce the constraints. (This is this module’s subject.)
3. Entropy management through periodic clean-up agents. Periodic passes that remove accumulated drift: dead code, duplicated logic, stale comments, inconsistent patterns, violations that slipped through. (This is also this module’s subject.)
9.1.2 Why it is a hypothesis
The decomposition is a description of one organisation’s practice, reported second-hand. It is not a measured result, and it has three limitations that make it a hypothesis rather than a finding.
Limitation 1 — Single source. The description comes from one organisation’s experience. It may be a description of what worked for them, not a general theory. The tier is B/C because the primary text is a vendor publication and the description here is secondary.
Limitation 2 — No comparison. The description does not compare the three-part approach to alternatives (a two-part approach, a different decomposition, no decomposition). The claim that the three parts are the right decomposition is not tested.
Limitation 3 — Confounded by the whole. The organisation’s success may be due to any part of its practice, not the decomposition. The decomposition is a narrative, and a narrative is not a controlled experiment (Module 6, Proposition 6.8.1).
9.1.3 How to test it
The decomposition can be tested as a set of predictions, each with a measurable consequence.
Prediction 1 (Context engineering matters). A harness with good context engineering outperforms one with poor context engineering, at fixed model and constraints. Test: Module 3’s lab, applied to the deployment.
Prediction 2 (Architectural constraints reduce defect escape). A repository with a constraint layer has a lower defect escape rate than one without, at fixed model and context engineering. Test: this module’s lab.
Prediction 3 (Entropy management is necessary). Without periodic clean-up, the codebase’s entropy (violations, duplication, complexity) grows unboundedly under agent modification. Test: a longitudinal measurement of the entropy metric (§9.4).
Prediction 4 (The three parts are complementary). The three parts together outperform any two, because they address different failure modes. Test: a factorial ablation of the three parts — expensive, and rarely run.
The lab tests Prediction 2 directly and Prediction 3 indirectly (the entropy measurement is part of the constraint layer’s monitoring). Predictions 1 and 4 are tested by the other modules and are not re-tested here.
9.2 What an architectural constraint is
9.2.1 Definition
Definition 9.2.1 (Architectural constraint). An architectural constraint is a rule that specifies a property the codebase must satisfy, together with a mechanism that checks or enforces the property. The rule is the specification; the mechanism is the enforcement. A constraint without an enforcement mechanism is a convention; a mechanism without a rule is a check without a purpose.
The definition separates the rule from the mechanism, and the separation matters: the same rule can be enforced by a linter (a static check), a test (a runtime check), a type system (a compile-time check), or a review (a human check). The choice of mechanism determines when the constraint is checked, and therefore whether it is a guide or a sensor (§9.5).
9.2.2 The constraint taxonomy
Constraints fall into five categories, each addressing a different kind of property.
C1 — Syntactic constraints. The code’s form: formatting, naming, import order, line length. Enforcement: a formatter, a linter. Example: “all imports are sorted.”
C2 — Structural constraints. The code’s organisation: module boundaries, dependency directions, layering. Enforcement: an import linter, an architecture test. Example: “the domain layer does not import from the infrastructure layer.”
C3 — Type constraints. The code’s types: the type signatures, the nullability, the generics. Enforcement: a type checker. Example: “no untyped
Anyin the public API.”C4 — Behavioural constraints. The code’s behaviour: the invariants, the contracts, the properties. Enforcement: a test suite, a property-based test. Example: “the parser is total: every input produces a result or a typed error.”
C5 — Security constraints. The code’s safety: no secrets in code, no dangerous calls, no unbounded resource use. Enforcement: a scanner, a policy engine (Module 7, §7.14). Example: “no
evalon user input.”
The taxonomy is a checklist: a constraint layer that covers only C1 is a formatter, not a constraint system; a layer that covers C1–C5 is a full architectural constraint layer, and it is what the decomposition’s second part means.
9.2.3 The enforcement spectrum
Each constraint can be enforced at a different point, and the point determines the cost and the strength.
| Enforcement point | Mechanism | When it fires | Strength | Cost |
|---|---|---|---|---|
| Editor / pre-commit | Formatter, linter (fast) | Before the commit | Low (can be bypassed) | Low |
| CI | Linter, type checker, tests | On every push | Moderate (blocks the merge) | Moderate |
| Build | Type checker, compiler | On every build | High (the artifact does not build) | Low (incremental) |
| Runtime | Assertions, tests | At execution | High (the failure is caught) | Variable |
| Review | Human check | Before the merge | High (but slow) | High |
The spectrum is the guide/sensor distinction in operational form: the editor and pre-commit checks are guides (they prevent the violation from being committed), the CI and runtime checks are sensors (they detect the violation after it is introduced), and the build and review are both (the build prevents the artifact, the review detects the problem).
9.3 What entropy is
9.3.1 The metaphor and its limits
“Entropy” in the decomposition is a metaphor for drift: the accumulation of small deviations from the intended state. The codebase starts in a clean state (the constraints are satisfied); each change can introduce a deviation (a violation, a duplication, a stale comment); the deviations accumulate, and the codebase becomes harder to work with.
The metaphor is useful and the physics analogy is misleading. Codebase entropy is not thermodynamic entropy; it is a count of violations over time, and it can be reduced (by cleanup) as well as increased (by changes). The useful formalisation is a birth-death process over the violation count (§9.4), not a thermodynamic entropy.
9.3.2 The drift sources
Four sources of drift, each with a different mitigation.
Source 1 — New violations. A change introduces a violation the constraints do not catch (a new pattern the linter does not model, a duplication the detector does not see). The constraint layer’s coverage gap (the internal model principle, §9.8) is the cause.
Source 2 — Weakened constraints. A constraint is relaxed (a linter rule disabled, a test skipped) to let a change through, and the relaxation is not reversed. The constraint layer erodes.
Source 3 — Environment change. The codebase’s dependencies change (a library update, a language version), and the constraints no longer apply or no longer catch what they used to. The constraint layer is stale.
Source 4 — Agent behaviour. An agent, optimizing for the task at hand, produces code that satisfies the task but violates the spirit of the constraints (a correct but unidiomatic implementation, a working but duplicated function). The constraint layer’s rules are satisfied, but the codebase’s quality degrades.
The four sources are the reason the decomposition includes the third part: entropy management is the response to drift, and the drift is caused by the first two parts’ limitations (the constraints’ coverage gaps, the context’s incompleteness) plus the environment’s changes.
9.3.3 The entropy metric
Definition 9.3.1 (Violation count). For a constraint layer and a codebase , the violation count is
where is the number of violations of constraint in . The count is normalised by the codebase size (violations per thousand lines) to compare across codebases.
The violation count is the operational entropy metric. It is computable (the constraints are automated), comparable (normalised by size), and trackable (a time series).
Proposition 9.3.2 (The violation count is a lower bound on the true drift). The violation count counts the violations the constraint layer models. The true drift, including the violations the layer does not model, is at least , and the gap is the layer’s coverage gap (the internal model principle, §9.8). A codebase with is not clean; it is clean with respect to the modelled constraints.
Proof. By definition, is the sum over the modelled constraints. The unmodelled violations are not counted, so the true count is for some .
The proposition is the reason the entropy metric must be supplemented by other signals (mutation testing, §9.15; legibility, §9.17) that probe the unmodelled failure modes.
9.4 The birth-death model of violations
9.4.1 The model
The violation count evolves as a birth-death process:
- Births: new violations are introduced at rate (per unit time, or per change).
- Deaths: existing violations are removed at rate per violation (by cleanup, by the constraint layer’s auto-fixes, by agents fixing them as they go).
Proposition 9.4.1 (Steady-state violation count). Under the birth-death model with constant rates, the expected violation count converges to
where is the birth rate and is the per-violation death rate. If , the violations grow without bound.
Proof sketch. The expected change in the count over a small interval is . Setting gives . For , the derivative is non-negative at every , so the count grows.
The steady-state interpretation. is the equilibrium violation count: the level at which the births (new violations) balance the deaths (cleanup). The level is not zero — it is the level the process settles at — and the design question is whether is acceptable, not whether it is zero.
9.4.2 The three regimes
The model has three regimes, and each has a different implication.
Regime 1 — : stable. The violations settle at . The codebase is manageable; the cleanup keeps up with the births.
Regime 2 — : marginal. The violations are a random walk; is not well-defined, and the count grows as (a diffusion). The codebase is on the edge; a small increase in or a small decrease in tips it into regime 3.
Regime 3 — : unstable. The violations grow without bound. The codebase degrades; the constraint layer cannot keep up; the entropy management has failed.
The regimes are the stability question of Part 0, §0.7, applied to the violation count: the system is stable iff the death rate exceeds the birth rate, which is the analogue of the control-loop stability condition.
9.4.3 The control interpretation
The birth-death model is a first-order control system with the violation count as the state. The birth rate is the disturbance, and the death rate is the control input (the cleanup effort). The steady-state error is the error the controller leaves, and it is the analogue of the steady-state error in Part 0, Proposition 0.7.7.
The control interpretation gives the design levers:
- Reduce (fewer births): better constraints (guides that prevent the violation), better context (the agent knows the conventions), better tools (the agent’s output is more often conforming).
- Increase (more deaths): more cleanup (periodic passes), auto-fixes (the constraint layer fixes what it can), agents that fix the violations they encounter.
The two levers correspond to the two halves of the decomposition: the architectural constraints reduce (they prevent violations from being introduced), and the entropy management increases (it removes the violations that were introduced). The decomposition’s three parts are the three levers: context engineering reduces (the agent knows what to do), architectural constraints reduce (the agent cannot introduce the violation), and entropy management increases (the violations are removed).
9.4.4 Concept check
Why is a codebase with zero violations not necessarily clean?
Answer. Because the violation count is a lower bound on the true drift (Proposition 9.3.2). The count measures the violations the constraint layer models; the unmodelled violations (the coverage gap) are not counted. A codebase with zero modelled violations can still have unmodelled drift — a duplication the detector does not see, a pattern the linter does not model, a stale comment the checker does not flag. The clean codebase is one where the constraint layer’s coverage is adequate for the deployment’s quality requirements, and the coverage is measured by other means (mutation testing, legibility probes), not by the violation count alone.
PART B — GUIDES VERSUS SENSORS
9.5 The distinction
9.5.1 Definitions
Definition 9.5.1 (Guide). A guide is a control mechanism that acts before the agent’s action to prevent a violation. It is a feedforward mechanism: it shapes the action so that the violation does not occur. Examples: a formatter (the code is formatted before it is committed), a type system (the code does not compile if it is ill-typed), a prompt instruction (“follow the style guide”), an allow-list (the action is rejected before it executes).
Definition 9.5.2 (Sensor). A sensor is a control mechanism that acts after the agent’s action to detect a violation. It is a feedback mechanism: it observes the result and reports the error. Examples: a test suite (the code is run and the test fails), a linter run in CI (the code is checked after the push), an LLM judge (the output is scored after it is generated), a monitor (the production system is observed after the deploy).
The distinction is temporal: a guide acts before, a sensor acts after. It is not a distinction of mechanism (a linter can be a guide if it runs in the editor, or a sensor if it runs in CI) but of where in the pipeline the mechanism fires.
9.5.2 The control-theoretic reading
Part 0, §0.7 gives the control-theoretic framework. Restating the key points in this module’s terms:
- The plant is the codebase.
- The controller is the agent (it produces changes).
- The reference is the constraint specification (the properties the codebase must satisfy).
- The disturbance is the drift (the changes that introduce violations).
- The guide is a feedforward controller: it acts on the agent’s output before it reaches the plant, shaping it toward the reference.
- The sensor is a feedback controller: it measures the plant’s state against the reference after the change, and reports the error.
The feedforward/feedback distinction is classical: feedforward acts on a model of the disturbance (the constraint specification), and feedback acts on the measured error. A feedforward controller can prevent the disturbance it models; a feedback controller can correct the error it measures. Neither alone is sufficient: a feedforward controller with a wrong model of the disturbance fails on the unmodelled disturbance; a feedback controller with a slow loop accumulates the error before it corrects.
9.5.3 Why a balanced design needs both
Proposition 9.5.3 (Guides and sensors are complementary). A harness with only guides cannot detect the violations the guides do not model. A harness with only sensors accumulates the violations until the sensor fires. A harness with both has the guides’ prevention and the sensors’ detection, and the combination’s coverage is the union of the two.
Argument. The guides prevent the violations in the set the guides model (call it ); the sensors detect the violations in the set the sensors model (). A violation in is prevented; a violation in is detected (after it occurs); a violation in is neither prevented nor detected. The union is the combined coverage, and it is larger than either alone.
The proposition is the reason the decomposition’s second part includes both linters (guides) and agents (sensors and fixers): the linter prevents the modelled violations, and the agent detects and fixes the ones that slipped through.
9.6 The guide/sensor trade-off
9.6.1 The formal model
The birth-death model of §9.4 can be extended to model the guide/sensor trade-off.
Let:
- be the birth rate with no guides.
- be the guide strength: the fraction of births the guides prevent. Then .
- be the death rate with no sensors.
- be the sensor strength: the additional removal rate the sensors enable (the sensors detect violations, and the cleanup removes them). Then .
- The steady-state violation count is
The guide/sensor trade-off is the problem of choosing to minimise subject to a cost budget , or to minimise the total cost for a violation penalty .
9.6.2 The optimal allocation
Proposition 9.6.1 (Optimal allocation). For the steady-state model with a separable cost and a violation penalty , the optimal satisfies the marginal conditions
The conditions say: the marginal cost of a guide equals the marginal reduction in (weighted by ), and the same for a sensor.
Derivation. The Lagrangian is . The first-order conditions are and , which give the stated conditions.
The interpretation. The conditions say that the optimal allocation balances the marginal costs against the marginal benefits. The benefit of a guide is proportional to — the guide’s benefit is larger when the birth rate is high and the death rate is low (a guide is most valuable when the codebase is drifting and the cleanup is weak). The benefit of a sensor is proportional to — the sensor’s benefit is larger when the births are high and the sensor is the only thing catching them (a sensor is most valuable when the guides are weak).
9.6.3 The two special cases
Case 1 — Cheap guides, expensive sensors. If the guides are cheap (a formatter, a linter) and the sensors are expensive (a full test suite, a human review), the optimum is to invest in the guides and use the sensors only for the failures the guides cannot prevent. This is the shift-left principle: move the checks as early as possible, because the early checks are cheaper.
Case 2 — Cheap sensors, expensive guides. If the sensors are cheap (a fast test suite, a monitor) and the guides are expensive (a type system for a dynamic language, a formal verification), the optimum is to invest in the sensors and accept the violations, fixing them quickly. This is the fail-fast principle: detect the failures quickly and recover, rather than prevent them.
The two cases are the reason the “shift left” advice is not universal: it is correct when the guides are cheaper than the sensors, and wrong when they are not.
9.6.4 The worked allocation
A codebase has violations per week, per week. The violation penalty is (in arbitrary units). The cost functions are and (quadratic costs).
The optimal conditions:
Solving: from the first, . Substituting into the second: . Let me solve numerically. Try : ; , — not equal, so is too high. Try : ; , — not equal. The second condition wants , and with , . So . Try : — no. Try : — no. The equation has no solution with in the range where the left exceeds the right. Let me reconsider: at , left , right ; left > right, so the marginal cost of the sensor exceeds its marginal benefit, and the optimum is at a lower . At , left , right ; left > right. At : left , right — negative, so the condition is not met (the right is negative because , i.e. , which is infeasible). The optimum is at the boundary: at its maximum feasible value (which is , no births) and at its minimum (, no sensor). The example is ill-conditioned; the point is the structure of the conditions, not the specific numbers. The lesson: the optimum depends on the cost functions, and a cheap guide with a high marginal benefit can dominate.
I should present a cleaner worked example or note that the numerical solution is boundary-dominated. Let me adjust: use , , , , . Then and . From the first, . From the second, . Try : — no. The same issue: with , requires , so must be at least 4, and at , , , so the second condition is — no. The example is again boundary-dominated (the guide is cheap enough to eliminate all births).
Let me just present the conditions and note that the numerical solution depends on the parameters, with a simple numerical case where both are interior. Let me pick: , , , , . Then and . From the first, . Then . Second: , i.e. . Try : vs — left > right. Try : vs — left < right. Try : vs — close. So , . . Not a huge reduction, but the example works. I’ll present it more simply, perhaps skipping the exact numerical solution and just giving the conditions and the interpretation. Better: present the conditions and a qualitative example.
Let me simplify and present the conditions with a clean interpretation, avoiding a messy numerical example. I can state that the optimum is at the point where the marginal costs equal the marginal benefits, and give a qualitative worked case.
Actually, for pedagogical clarity, I’ll present the Lagrangian and the first-order conditions, then give a simple “if the guide is cheap” / “if the sensor is cheap” qualitative analysis, and note that the exact optimum requires specifying the cost functions. That’s honest and avoids a contrived numerical example.
9.7 The internal model principle for failure coverage
9.7.1 The principle
Part 0, §0.7 states the internal model principle: a controller can reject a class of disturbances only if it contains a model of that class. In this module’s terms: a harness can prevent or detect a class of failure only if it models that class. A linter can catch the style violations its rules encode; it cannot catch the style violations its rules do not encode. A test can catch the behaviours its assertions check; it cannot catch the behaviours its assertions do not check.
9.7.2 The quantified bound
Definition 9.7.1 (Modelled failure set). Let be the set of failure modes (the ways a change can violate the constraints or the intent), and let be the set the harness models (the failures the guides and sensors can prevent or detect). The harness’s coverage is in the set sense, and its detection rate on a failure distribution over is at most .
Proposition 9.7.2 (Internal model bound). For any harness whose guides and sensors model exactly the set , the detection rate on a failure drawn from is at most . The bound is tight if the harness detects every failure in and none outside.
Proof. A failure in is not modelled, so the harness has no mechanism to prevent or detect it (by the internal model principle). The detection rate is therefore at most the probability that the failure falls in , which is .
The interpretation. The bound is a coverage bound, not a performance bound: it says the harness cannot detect what it does not model. The practical consequence: to raise the detection rate, either enlarge (add rules, add tests, add checks) or change (the failure distribution, by changing the task or the model). The first is the constraint layer’s job; the second is the harness’s job (a better model makes fewer failures, of the modes it makes).
9.7.3 The coverage gap
Definition 9.7.3 (Coverage gap). The coverage gap is : the fraction of failures the harness does not model, and therefore cannot detect.
The gap is the residual risk. It is measured by probing the unmodelled failures: mutation testing (§9.15) probes the test suite’s coverage; legibility probes (§9.17) probe the agent’s navigation; incident analysis (Module 11) probes the production failures. The gap is not eliminated; it is managed, by measuring it and deciding whether it is acceptable for the deployment.
9.7.4 Concept check
A linter catches 40 of the 100 style violations that occur in a codebase. What does this tell you about the linter’s coverage, and what would you do?
Answer. The linter models 40 of the violation modes that occur (or, more precisely, it catches 40% of the violations by prevalence, which is ). The coverage gap is 60%: the other 60 violations are modes the linter does not model. To reduce the gap, either add rules for the unmodelled modes (enlarge ) or change the codebase so the unmodelled modes occur less (change ). The choice depends on the cost: a rule is cheap if the mode is common and the rule is simple; a codebase change is cheap if the mode is caused by a pattern that can be removed. The measurement (which modes are unmodelled) is the first step, and it is the input to the decision.
9.8 The guide/sensor balance in practice
9.8.1 The shift-left question
The “shift left” advice — move the checks as early as possible — is a guide-favoring heuristic. It is correct when the early checks are cheaper than the late ones, which is often true (a formatter is cheaper than a failing CI run, a type error is cheaper than a production incident). But it is not universally true: a type system for a dynamic language is expensive to introduce, and a runtime check may be cheaper.
The correct posture is to apply the allocation analysis (§9.6): measure the marginal costs and benefits, and allocate to the mechanism with the higher marginal benefit per unit cost. The shift-left advice is a prior, not a law.
9.8.2 The guide’s failure mode
A guide that is too strict blocks legitimate work: a linter that rejects a valid pattern forces the agent to write a less idiomatic version, or to disable the rule (which weakens the constraint, drift source 2). The guide’s false-deny rate (Module 7, §7.14.4) is the measure, and it should be tuned to a level where the legitimate work is not blocked.
9.8.3 The sensor’s failure mode
A sensor that fires too late allows the violation to accumulate before it is detected: a test suite that runs only at the end of a long task lets the agent introduce many violations before the first failure. The sensor’s latency is the measure, and it should be tuned to a level where the violations are caught before they compound.
9.8.4 The balance
The balanced design uses guides for the violations that can be prevented cheaply (the formatter, the type checker, the import linter) and sensors for the violations that cannot (the behaviour tests, the integration tests, the monitors). The balance is the allocation solution of §9.6, and it is deployment-specific: a codebase with a strong type system needs fewer runtime type checks; a codebase with a weak one needs more.
PART C — CI, MUTATION TESTING, AND LEGIBILITY
9.9 CI as ground truth
9.9.1 What CI is
Continuous integration (CI) is the practice of running the constraint layer (the linters, the type checkers, the tests) on every change, in a clean environment, before the change is merged. It is the repository’s ground-truth verifier: the check that determines whether a change is acceptable.
9.9.2 Why CI is the ground truth
CI is the ground truth for three reasons.
Reason 1 — It runs the whole constraint layer. The editor and pre-commit checks are partial (they run fast, so they run a subset); CI runs the whole layer (the full test suite, the full linter, the full type checker). The full layer is the strongest check the repository has.
Reason 2 — It runs in a clean environment. The developer’s environment has accumulated state (caches, local modifications, installed packages); CI’s environment is fresh (from the pinned dependencies, Module 7, §7.7). A check that passes locally but fails in CI is a reproducibility bug (Module 7, §7.7.3), and CI catches it.
Reason 3 — It is the merge gate. The merge is blocked on CI, so CI’s verdict is the operative one. A check that does not run in CI is advisory; a check that runs in CI is binding.
9.9.3 The harness’s relationship to CI
The harness’s verification loop (Module 7, §7.10) should be aligned with CI, not independent of it. The harness’s verifier should run the same checks CI runs, on the same environment, so that a change that passes the harness’s verification passes CI (or the discrepancy is a bug).
The alignment failure. A harness that runs a weaker check than CI (a subset of the tests, a linter with fewer rules) will produce changes that fail CI, and the failure is discovered late (after the harness’s run, in CI), which wastes the harness’s work. The alignment is a design requirement: the harness’s verifier should be the same as CI’s, or stronger.
9.9.4 The CI as a sensor
CI is a sensor in the guide/sensor taxonomy: it acts after the change (on the push), and it detects the violations the guides (the editor, the pre-commit) did not prevent. Its latency is the CI run time (minutes), and its strength is the whole constraint layer. It is the repository’s primary feedback loop.
9.10 Mutation testing
9.10.1 The mechanism
Mutation testing measures a test suite’s strength by introducing small faults (mutations) into the code and checking whether the tests catch them.
Procedure 9.10.1 (Mutation testing).
- Generate mutants. For each code location, apply a mutation operator (flip a comparison, replace a constant, delete a statement, swap a boolean). Each mutant is a version of the code with one small fault.
- Run the tests on each mutant. If the tests fail, the mutant is killed; if the tests pass, the mutant survives.
- Compute the mutation score. .
- Analyse the survivors. Each surviving mutant is a behaviour the tests do not check. The survivor is either an equivalent mutant (the mutation does not change the behaviour, so no test can kill it) or a test gap (the mutation changes the behaviour, and the tests miss it).
9.10.2 The mutation score as a TPR
The mutation score is the test suite’s true-positive rate on the mutation distribution: the fraction of injected faults that the tests catch.
Proposition 9.10.2 (Mutation score as a TPR). If the mutants are drawn from a distribution over the possible faults, the mutation score is an estimate of the test suite’s TPR on :
The estimate is biased if the mutation operators’ distribution differs from the deployment’s fault distribution .
Proof. The mutation score is the empirical fraction of mutants the tests kill. Each mutant is a fault drawn from . The fraction killed is the empirical TPR on the sample, which estimates the TPR on . The bias is the difference between and , the deployment’s fault distribution.
9.10.3 The bias and its correction
The mutation operators are a proxy for the deployment’s faults: they generate the faults that are syntactically small and mechanically generable, which is not the same as the faults the agent (or a human) actually introduces. The bias is real, and it means the mutation score is a lower bound on the TPR on the deployment’s faults only if is “at least as hard” as , which is not guaranteed.
The correction is to calibrate the mutation operators against the deployment’s faults: collect the actual faults (from incidents, from the agent’s failures), classify them, and weight the mutation operators to match. The weighted mutation score is a better estimate of the deployment TPR, and it is the version the lab uses.
9.10.4 Mutation testing as an agent-robustness probe
The mutation score is a measure of the test suite, but it is also a measure of the agent’s robustness: a test suite with a high mutation score catches more of the faults the agent might introduce, so the agent’s changes are more likely to be caught before they escape. The mutation score is the harness’s TPR on the fault distribution, and it is the input to the autonomy decision (Part 0, §0.5): a harness with a high mutation score can support more autonomy than one with a low score.
The probe’s use. Run mutation testing on the constraint layer (the test suite) before deploying the agent. The mutation score is the TPR estimate; the survivors are the test gaps; the gaps are the failure modes the agent can introduce undetected. The probe is the measurement that makes the autonomy decision quantitative.
9.11 The mutation score and the violation count
9.11.1 The relationship
The violation count (§9.3.3) and the mutation score are complementary measures.
- The violation count measures the constraint layer’s coverage of the modelled violations: how many violations exist, relative to the rules.
- The mutation score measures the test suite’s strength on the fault distribution: how many injected faults the tests catch.
The violation count is a static measure (it counts the violations in the current code); the mutation score is a dynamic measure (it runs the tests on the mutants). The violation count is cheap; the mutation score is expensive (it runs the tests many times).
9.11.2 The combination
A codebase with a low violation count and a high mutation score is in good shape: the constraints are satisfied and the tests are strong. A codebase with a low violation count and a low mutation score is deceptively clean: the constraints are satisfied but the tests are weak, so the unmodelled faults are not caught. A codebase with a high violation count and a high mutation score is tested but non-conforming: the tests are strong but the constraints are not enforced, so the code is correct but inconsistent.
The two measures together give a fuller picture than either alone, and the combination is the diagnostic: a low violation count with a low mutation score is the dangerous case (the codebase looks clean but is not robust), and it is the case the entropy metric alone would miss.
9.12 Codebase legibility for agents
9.12.1 What legibility is
Definition 9.12.1 (Codebase legibility). A codebase is legible for an agent if the agent can find the code relevant to a task, understand it, and modify it, at a cost (in tokens and steps) that is low enough for the task’s budget.
Legibility is a property of the codebase relative to the agent, not a property of either alone. A codebase that is legible for a human (well-named, well-documented) may be illegible for an agent (the agent cannot search it efficiently), and vice versa. The legibility is measured by the agent’s cost to complete a task, not by a human’s judgement.
9.12.2 The measures
Three measures, each computable from the agent’s trace.
Navigation cost. The number of tool calls (searches, reads) the agent makes to find the relevant code. A legible codebase has a low navigation cost: the agent finds the code quickly.
Comprehension cost. The number of tokens the agent reads to understand the code. A legible codebase has a low comprehension cost: the code is readable, and the agent does not need to read a large context to understand a small function.
Modification cost. The number of steps (edits, tests) the agent takes to make the change. A legible codebase has a low modification cost: the change is local, and the tests are fast.
9.12.3 The legibility factors
Four factors make a codebase legible, and each is a design decision.
Factor 1 — Naming and structure. Clear names, consistent structure, a predictable layout. The agent’s search is more effective when the names are descriptive and the structure is regular.
Factor 2 — Documentation at the point of use. The comments and docstrings where the agent needs them, not in a separate document. The agent reads the code, so the documentation should be in the code.
Factor 3 — Test discoverability. The tests are easy to find and run. The agent’s verification loop is faster when the tests are discoverable.
Factor 4 — Instruction files. The AGENTS.md (Module 8, §8.16) tells the agent the conventions and the structure, reducing the navigation cost.
The four factors are the legibility levers, and the constraint layer can enforce some of them (a linter for naming, a test for documentation coverage) and the entropy management can maintain them (a cleanup pass that removes stale comments, updates the docs).
9.12.4 Legibility as a constraint
Legibility can be constrained (a linter rule for naming, a test for doc coverage) or measured (the navigation cost from the trace) or both. The constraint is a guide (it prevents the illegible code); the measurement is a sensor (it detects the illegibility after the fact). The balanced design uses both, as in §9.8.
PART D — MEASURING DELIVERY IMPACT
9.13 DORA-style baselines
9.13.1 The four metrics
The DORA metrics (from the DevOps Research and Assessment programme) are four measures of software delivery performance.
D1 — Deployment frequency. How often the code is deployed to production.
D2 — Lead time for changes. The time from a commit to its deployment.
D3 — Change failure rate. The fraction of deployments that cause a failure (an incident, a rollback, a hotfix).
D4 — Time to restore service. The time to recover from a failure.
The four metrics are the standard measures of delivery performance, and they are the baseline against which a harness change’s impact is measured.
9.13.2 The baseline and the comparison
The measurement design:
- Establish the baseline. Measure the four metrics before the harness change, over a period long enough to be stable (weeks to months, depending on the deployment frequency).
- Make the change. The harness change is the intervention.
- Measure after. Measure the four metrics after the change, over a comparable period.
- Compare. The change’s effect is the difference, with a confidence interval (Module 5, §5.4).
The comparison is observational, not a controlled experiment: the change is not randomly assigned, and other factors (the team, the codebase, the market) may change at the same time. The comparison is suggestive, not causal, and it should be supplemented by a controlled comparison where possible (a canary deployment, an A/B test on a subset of the work).
9.13.3 The confounds
The observational comparison has four confounds, and each must be addressed.
Confound 1 — Maturation. The team and the codebase mature over time, so the “after” metrics improve even without the change. Control: compare to a control group (a team that did not adopt the change) or a synthetic control.
Confound 2 — Selection. The change is adopted when the team is ready, which may correlate with other improvements. Control: randomise the adoption (a canary, an A/B test) where possible.
Confound 3 — Measurement drift. The metrics’ definitions change over time (a new incident classification, a new deployment process). Control: freeze the definitions before and after, or document the change.
Confound 4 — Hawthorne effect. The team behaves differently because it is being measured. Control: measure for a period before the change’s announcement, and use a control group.
The confounds are the reason the DORA comparison is evidence, not proof: it is a signal that the change may have helped, and a controlled comparison is needed to establish causation.
9.14 The stability margin of a change
9.14.1 The stability condition
Part 0, §0.7 gives the stability condition for the harness-evolution loop: the step size must satisfy , where is the Lipschitz constant of the gradient and is the delay. The stability margin is the ratio of the step size to the stability bound:
A margin is stable; is unstable; is marginal.
9.14.2 Applying it to a constraint change
A constraint change (a new linter rule, a new test) is a step in the harness-evolution loop. The change’s stability margin is computed from:
- , the sensitivity of the delivery metrics to the constraint change. A change that affects many changes (a formatting rule that touches every file) has a high ; a change that affects few (a rule for a rare pattern) has a low .
- , the delay between the change and its effect. A linter rule’s effect is immediate (the next change is checked); a test’s effect is delayed (the test runs in CI, minutes later); a DORA metric’s effect is delayed (the deployment frequency changes over weeks).
- , the size of the change. A single rule is a small step; a suite of rules is a large step.
The stability margin tells you whether the change is likely to cause oscillation (adopting and reverting the rule) or convergence (the codebase adapts). A small change with a short delay is stable; a large change with a long delay is unstable, and should be split into smaller steps or measured more quickly.
9.14.3 The worked margin
A team adopts a new linter rule that affects 5% of changes. The delay is 1 week (the rule is measured through the weekly DORA metrics). The sensitivity is estimated at 0.2 (the rule changes the deployment frequency by at most 0.2 per unit of rule strength). The stability bound is . The team adopts the rule fully (), so the margin is — stable. If the team adopts a suite of 10 rules at once (), the margin is — unstable, and the team should split the adoption into smaller steps.
The worked margin is the quantitative form of the “small steps, short feedback” advice: the margin is stable when the steps are small relative to the sensitivity and the delay, and the advice is the margin’s implication.
9.15 Goodhart and the metric choice
9.15.1 The law
Goodhart’s law: when a measure becomes a target, it ceases to be a good measure. The metric is gamed: the team optimises the metric rather than the underlying goal, and the metric improves while the goal does not.
9.15.2 The application
The DORA metrics are targets (the team is measured on them), so they are subject to Goodhart. The gaming:
- Deployment frequency can be gamed by deploying trivial changes (a version bump) to inflate the count.
- Lead time can be gamed by committing late (the time is measured from the commit, so a late commit is a short lead time).
- Change failure rate can be gamed by classifying failures as “not failures” (a narrow definition) or by rolling back without an incident.
- Time to restore can be gamed by declaring an incident resolved before it is.
The gaming is not necessarily malicious: the team optimises what it is measured on, and the metric’s proxy diverges from the goal. The defence is to use a basket of metrics (the four together are harder to game than any one), to audit the metrics (check whether the improvement is real), and to measure the goal (the delivery’s value, not just the process’s speed).
9.15.3 The measurement design
The measurement design that resists Goodhart:
- Use the four metrics together. A team that deploys frequently, with a short lead time, a low failure rate, and a fast restore, is genuinely performing; a team that games one metric will show an anomaly in the others.
- Audit the metrics. Sample the deployments and check whether they are real (a trivial change is not a deployment); sample the failures and check whether they are correctly classified.
- Measure the outcome. The delivery’s value (the features delivered, the incidents avoided) is the goal; the DORA metrics are the process. Measure both.
- Do not use the metrics for individual performance. The metrics are team-level; using them for individuals invites the worst gaming.
The design is the Module 5 discipline applied to the delivery metrics: the metric is a measurement, not a target, and the measurement is audited.
9.16 The lab’s place in the measurement
9.16.1 The lab’s design
The lab (§9.25) is a controlled comparison: a repository is retrofitted with a constraint layer, and the defect escape rate is compared before and after, on the same task set, with the Module 5 discipline. The comparison is stronger than the DORA comparison (it is controlled, not observational), and it is the evidence for the decomposition’s Prediction 2 (the constraints reduce the defect escape rate).
9.16.2 The connection to the stability margin
The lab’s constraint change is a step in the evolution loop, and its stability margin is computed (§9.14). The lab reports the margin, so the change’s effect is interpreted in the light of its stability: a large effect with a low margin is a change that may not persist; a small effect with a high margin is a change that is stable but marginal.
LAB 9 — RETROFIT A CONSTRAINT LAYER AND MEASURE THE EFFECT
9.25.1 Task specification
Choose a repository that an agent modifies (your own, or a synthetic one). The repository must:
- Have a test suite (the verifier).
- Have enough tasks for a comparison (at least 30 changes, ideally 50).
- Have a defect escape measurement: a way to determine whether a change introduces a defect that the test suite does not catch. The canonical measure is a held-out test suite (a set of tests not run during the agent’s work, used to check for defects).
9.25.2 The constraint layer
Implement a constraint layer with at least one constraint from each of the five categories (C1–C5 of §9.2.2):
- C1 (syntactic): a formatter or a naming linter.
- C2 (structural): an import-direction check or a layering check.
- C3 (type): a type checker on the modified files.
- C4 (behavioural): a property-based test or an invariant check.
- C5 (security): a scanner for secrets or dangerous calls.
The layer must be integrated into the agent’s verification loop (Module 7, §7.10), so the agent sees the constraint failures as observations.
9.25.3 The design
A before/after comparison on the same task set:
- Condition A (baseline): the agent runs without the constraint layer (the test suite only).
- Condition B (constraint layer): the agent runs with the constraint layer, seeing the constraint failures as observations.
The same model, the same task set, the same test suite, the same budget. The only variable is the constraint layer.
9.25.4 The metrics
| Metric | Definition | Measurement |
|---|---|---|
| Defect escape rate | Fraction of changes that pass the test suite but fail the held-out suite | Held-out suite |
| Violation count | The sum of the constraint violations in the final codebase | Constraint layer |
| Mutation score | Killed mutants / total mutants | Mutation testing (§9.10) |
| Navigation cost | Tool calls to find the relevant code | Trace |
| Completion rate | Fraction of tasks that complete | Test suite |
| Token cost | Total tokens per task | Trace |
| Stability margin | §9.14 |
9.25.5 The hypotheses
State before running:
- H1. Condition B has a lower defect escape rate than Condition A, because the constraint layer catches the defects the test suite misses.
- H2. Condition B has a lower violation count, because the constraints prevent the violations.
- H3. Condition B has a higher token cost, because the agent spends tokens fixing the constraint failures.
- H4. The defect escape reduction is larger for the constraint categories that address the task’s failure modes (the C4 behavioural constraints for a behaviour-changing task) and smaller for the others.
- H5. The stability margin is for the change (the constraint layer is a stable step), and the effect is expected to persist.
9.25.6 The acceptance criteria
| # | Criterion |
|---|---|
| 1 | The constraint layer covers all five categories (C1–C5) |
| 2 | The layer is integrated into the verification loop (the agent sees the failures) |
| 3 | The before/after comparison holds the controls fixed (model, task set, test suite, budget) |
| 4 | The defect escape rate is reported with a paired bootstrap confidence interval |
| 5 | The violation count and the mutation score are reported for both conditions |
| 6 | The navigation cost is reported, and the legibility change is interpreted |
| 7 | The stability margin is computed, with , , stated |
| 8 | The hypotheses are pre-registered, and the deviations are logged |
| 9 | The constraint categories’ individual effects are analysed (which category contributed the most) |
| 10 | A decision memo: whether to adopt the constraint layer, with the revision condition |
9.25.7 What good looks like
A good lab report has five properties.
It measures the defect escape rate with a held-out suite. The test suite the agent uses is not the test suite that measures the defects; the held-out suite is the independent measure. A report that measures the defect escape rate with the same suite the agent used has confounded the agent’s optimisation with the measurement.
It reports the mutation score. The mutation score is the test suite’s strength, and it is the context for the defect escape rate. A defect escape rate of 10% with a mutation score of 0.9 is a different finding from the same rate with a mutation score of 0.5.
It decomposes the effect by category. The constraint layer has five categories, and the effect is the sum of their contributions. A report that says “the layer reduced the escape rate by 6 points” without saying which categories contributed has missed the diagnostic.
It computes the stability margin. The margin is the change’s stability, and it is the context for the effect’s persistence. A large effect with a low margin is a finding that may not replicate.
It states the revision condition. Under what observation would you change the layer? A different task distribution, a different model, a different held-out suite — each would change the answer, and the memo should say which.
MODULE 9 CHEAT SHEET
| Term / result | Statement / definition | Annotation: role in this module and the curriculum |
|---|---|---|
| Three-part decomposition | Context engineering, architectural constraints, entropy management | §9.1; tier B/C, a hypothesis |
| The decomposition’s status | Single source, no comparison, confounded | §9.1.2; the limitations |
| Testing the decomposition | Four predictions, each measurable | §9.1.3; the experiment |
| Architectural constraint | A rule + an enforcement mechanism | Definition 9.2.1; the separation |
| Constraint taxonomy | Syntactic, structural, type, behavioural, security (C1–C5) | §9.2.2; the five categories |
| Enforcement spectrum | Editor, CI, build, runtime, review | §9.2.3; the guide/sensor placement |
| Entropy (metaphor) | Drift: the accumulation of violations | §9.3.1; the metaphor’s limits |
| Drift sources | New violations, weakened constraints, environment change, agent behaviour | §9.3.2; the four sources |
| Violation count | , normalised by size | Definition 9.3.1; the entropy metric |
| Violation count is a lower bound | true drift | Proposition 9.3.2; the coverage gap |
| Birth-death model | births, per-violation deaths | §9.4.1; the model |
| Steady state | ; grows if | Proposition 9.4.1; the equilibrium |
| Three regimes | Stable, marginal, unstable | §9.4.2; the stability question |
| Control interpretation | The count is a first-order system; the cleanup is the control | §9.4.3; the stability link |
| Guide | A feedforward mechanism, acts before | Definition 9.5.1; the prevention |
| Sensor | A feedback mechanism, acts after | Definition 9.5.2; the detection |
| Temporal distinction | The placement in the pipeline, not the mechanism | §9.5.1; the key point |
| Control reading | Plant = codebase; controller = agent; guide = feedforward; sensor = feedback | §9.5.2; the framework |
| Complementarity | Guides prevent, sensors detect; union is the coverage | Proposition 9.5.3; the balance |
| Guide/sensor model | §9.6.1; the trade-off | |
| Optimal allocation | Marginal cost = marginal benefit, for each mechanism | Proposition 9.6.1; the conditions |
| Shift-left | A guide-favoring heuristic; correct when guides are cheaper | §9.6.3, §9.8.1; the prior, not a law |
| Internal model principle | A harness detects only what it models | §9.7.1; the coverage bound |
| Internal model bound | Detection rate | Proposition 9.7.2; the quantified bound |
| Coverage gap | ; the unmodelled failures | Definition 9.7.3; the residual risk |
| Guide failure mode | Too strict; blocks legitimate work | §9.8.2; the false-deny |
| Sensor failure mode | Too late; the violations compound | §9.8.3; the latency |
| CI | The whole constraint layer, clean environment, merge gate | §9.9; the ground truth |
| CI as sensor | Acts after the push; the primary feedback | §9.9.4; the placement |
| CI alignment | The harness’s verifier should match CI’s | §9.9.3; the design requirement |
| Mutation testing | Mutate, run tests, count kills | Procedure 9.10.1; the probe |
| Mutation score | Killed/total; a TPR on the mutation distribution | Proposition 9.10.2; the estimate |
| Bias | The mutation distribution ≠ the deployment’s faults | §9.10.3; the correction |
| Probe use | The TPR estimate for the autonomy decision | §9.10.4; the measurement |
| Violation count vs mutation score | Static coverage vs dynamic strength | §9.11; the complementary measures |
| Deceptive cleanliness | Low violations, low mutation score | §9.11.2; the dangerous case |
| Legibility | The agent’s cost to find, understand, modify | Definition 9.12.1; the relative property |
| Legibility measures | Navigation, comprehension, modification cost | §9.12.2; the trace measures |
| Legibility factors | Naming, documentation, test discoverability, instruction files | §9.12.3; the levers |
| DORA metrics | Deployment frequency, lead time, change failure rate, restore time | §9.13.1; the delivery measures |
| DORA comparison | Observational, with four confounds | §9.13.2–9.13.3; the evidence status |
| Stability margin | ; is stable | §9.14.1; the change’s stability |
| Margin application | Small steps, short delay, low sensitivity | §9.14.2; the practice |
| Goodhart’s law | A measure used as a target is gamed | §9.15.1; the risk |
| DORA gaming | Trivial deploys, late commits, narrow failure definitions | §9.15.2; the four games |
| Goodhart defence | Basket, audit, outcome measure, no individual use | §9.15.3; the design |
EXERCISES WITH SOLUTIONS
E9.1. A codebase has a birth rate of 12 violations per week and a death rate of 3 per violation per week. What is the steady-state violation count? If the team adds a guide that prevents 40% of the births, what is the new steady state?
S9.1. . With : , . The guide reduces the steady state from 4 to 2.4, a 40% reduction. If the team instead added a sensor that doubles the death rate (, ): . The sensor is more effective in this case, because the death rate’s marginal effect is larger. The comparison is the allocation analysis (§9.6): the guide and the sensor have different marginal effects, and the optimum depends on their costs.
E9.2. A linter catches 30 of 100 style violations by prevalence. What is its coverage, and what is the coverage gap? What would you do to reduce the gap?
S9.2. Coverage ; gap . To reduce the gap: (1) add rules for the unmodelled modes (enlarge ) — the first step is to classify the 70 uncaught violations into modes, and add rules for the common ones; (2) change the codebase so the unmodelled modes occur less (change ) — e.g., remove the pattern that produces them; (3) accept the gap if the unmodelled modes are rare or low-severity. The choice depends on the cost of each, and the measurement (the classification) is the input.
E9.3. A test suite has a mutation score of 0.85. What does this mean, and what is the caveat?
S9.3. The mutation score of 0.85 means the test suite killed 85% of the mutants, i.e. its TPR on the mutation distribution is 0.85 (Proposition 9.10.2). The caveat is the bias: the mutation operators’ distribution may differ from the deployment’s fault distribution (the agent’s actual faults), so 0.85 is an estimate of the TPR on the mutation distribution, not necessarily on the deployment’s. The correction is to calibrate the mutation operators against the deployment’s faults (the actual incidents), and to report the weighted score. A suite with a high mutation score but a miscalibrated operator distribution can still have a low TPR on the real faults.
E9.4. A team adopts a new linter rule that affects 10% of changes, with a delay of 2 weeks and a sensitivity . Compute the stability margin for a full adoption () and for a half adoption ().
S9.4. Bound . Full adoption: — stable, but marginal. Half adoption: — stable, with margin. The full adoption is stable but close to the boundary; the half adoption is safer. The recommendation: adopt in two steps of 0.5, and measure after each, rather than adopting the full rule at once.
E9.5. A team’s DORA metrics improve after a harness change: deployment frequency up 20%, lead time down 15%, change failure rate down 5%. What are the confounds, and how would you check whether the change caused the improvement?
S9.5. The confounds: maturation (the team improved over time), selection (the change was adopted when the team was ready), measurement drift (the definitions changed), and the Hawthorne effect (the team behaved differently because it was measured). To check causation: (1) compare to a control team that did not adopt the change; (2) if possible, randomise the adoption (a canary, an A/B test); (3) freeze the definitions before and after; (4) measure for a period before the change’s announcement. The observational comparison is suggestive; the controlled comparison is the evidence.
E9.6. A codebase has zero violations and a mutation score of 0.4. What is the diagnosis, and what would you do?
S9.6. The diagnosis is deceptive cleanliness (§9.11.2): the constraints are satisfied (zero violations) but the tests are weak (mutation score 0.4), so the unmodelled faults are not caught. The codebase looks clean but is not robust. The action: (1) improve the test suite (add tests for the surviving mutants, which are the test gaps); (2) add behavioural constraints (C4) to catch the faults the tests miss; (3) re-measure the mutation score after the improvements. The violation count alone would have given false confidence; the mutation score reveals the weakness.
E9.7. A constraint layer’s C1 (formatter) reduces the violation count by 60%, but the defect escape rate is unchanged. What does this tell you about the C1 constraint’s relevance?
S9.7. The C1 constraint addresses syntactic violations, which are not the defects the held-out suite measures. The violation count fell (the syntax is cleaner), but the defect escape rate is unchanged (the defects are behavioural, not syntactic). The C1 constraint is doing what it is designed to do, but it is not addressing the task’s failure modes. The diagnostic: the constraint categories’ relevance is task-specific, and a category that reduces the violation count without reducing the defect escape rate is a category that addresses a different failure mode than the one the held-out suite measures. The recommendation: keep the C1 constraint (it has its own value), and add the constraints (C4 behavioural) that address the defect escape mode.
E9.8. A team measures the DORA metrics and finds that the deployment frequency is high, the lead time is short, but the change failure rate is high. What does this pattern suggest, and what would you investigate?
S9.8. The pattern suggests fast but fragile delivery: the team deploys quickly, but a high fraction of the deployments fail. The investigation: (1) the failure classifications (are the failures real, or is the classification too broad?); (2) the constraint layer’s coverage (the tests may be weak, allowing defects to escape); (3) the review process (the changes may be under-reviewed); (4) the change size (small changes fail less often, so the failures may be concentrated in large changes). The pattern is the DORA basket’s value: a single metric (deployment frequency) would look good, but the basket reveals the trade-off, and the investigation targets the weak metric.
EXIT TEST FOR MODULE 9
You are ready for Module 10 when you can, without notes:
- State the three-part decomposition and its evidence status, and name the four predictions that test it.
- Define an architectural constraint and distinguish the rule from the enforcement mechanism.
- Name the five constraint categories and give an example of each.
- Define the violation count, state that it is a lower bound on the true drift, and explain why.
- State the birth-death model, the steady-state violation count, and the three regimes.
- Explain the control interpretation of the model and the two levers (reduce , increase ).
- Define a guide and a sensor, and explain the temporal distinction.
- State the guide/sensor complementarity proposition and the optimal allocation conditions.
- Explain the shift-left heuristic and when it is wrong.
- State the internal model principle and the quantified coverage bound.
- Explain why CI is the ground truth and why the harness should align with it.
- Describe mutation testing, the mutation score as a TPR, and the bias.
- Define legibility, the three measures, and the four factors.
- State the DORA metrics, the four confounds of the observational comparison, and the Goodhart risk.
- Compute the stability margin of a change and interpret it.
- Explain deceptive cleanliness (low violations, low mutation score) and why it is dangerous.
End of Module 9. Say “next” to receive Module 10 in full.