git:20260903.f199530 to git:20260906.e6ad4bd
72 added, 182 removed. Audit A to A.
---
name: architecture-fitness-functions
description: >
- The governance decision for an architecture characteristic — what to govern, at what threshold, where,
- and what happens when it goes red — not how the test is written: the objectivity test, triaging an
- inherited suite, and marking a characteristic explicitly ungoverned. Use when incidents pass a gate that
- stayed green, when rules are skipped or red on main and nobody remembers why, when a driving
- characteristic has no check, when "maintainable" is proposed as the thing to measure, when a scanner
- ships a threshold that cannot fail, when a frozen baseline has not shrunk in a year, when an SLO
- dashboard is called a fitness function but nothing stops, or when a green pipeline reads as
- architectural health. Does not cover writing the test (architecture-testing), pipeline composition and
- ratcheting onto legacy code (quality-gates), deriving the list (architecture-characteristics), the
- analysis method (architecture-trade-off-analysis), CI thresholds (performance-regression-ci), or error
- budgets (slo-and-alerting).
+ Define or review checks that preserve architectural qualities when a green pipeline misses
+ incidents, inherited rules are skipped or unexplained, a characteristic lacks evidence,
+ or a metric is being promoted to a blocking gate. Choose the measurement or rubric,
+ threshold, execution site, owner and response policy; expose proxy limits and coverage gaps.
+ Excludes selecting quality drivers (architecture-characteristics), implementing application
+ tests (architecture-testing), pipeline composition (quality-gates), performance experiment
+ thresholds (performance-regression-ci) and operational error-budget design (slo-and-alerting).
---
# Architecture Fitness Functions
- ## Purpose
-
- One line decides everything. Rebecca Parsons: _"The single most important thing about a fitness function
- is that you and I will never disagree on whether it passes or not."_ (Thoughtworks Podcast, 6 Mar 2025.)
- **A fitness function needs an operational decision rule whose result is reproducible within stated
- measurement uncertainty.** Competent people may still disagree about whether the proxy, threshold,
- or consequence represents the intended characteristic; that is a governance defect to expose, not
- proof that no fitness function exists. The books add
- _"an objective integrity assessment of some architecture characteristic"_ (_Fundamentals_ ch. 6; _BEA_
- ch. 2 — via reader notes, so no page is claimed), leaving two clauses implicit: **a fitness function
- is a metric, a threshold, a site and a consequence.** No consequence, a dashboard; no site, a wish.
-
- ## When to use — and when not
-
- The unit is **independent change sources**: how many teams, contractors or agents can merge a change to
- the thing the rule protects without a shared reviewer. `architecture-characteristics` moved off headcount
- onto quantum count because quanta measure the problem; here the organisation _is_ the problem.
-
- - **One source, characteristic met with margin** — review already catches it. Write the rule in the ADR,
- record it ungoverned, and name the trigger: a second team, a merge bot, an agent with commit rights.
- - **Use it** when a driving characteristic can be violated by someone not in the review, or once it has
- been violated; Juhls & Morales (AWS, 22 Jul 2021) advise starting with about three.
- - **Not here:** how the test is written (`architecture-testing`); which checks a change must pass, or
- introducing one onto a codebase that fails it (`quality-gates`).
-
- ## Before deciding, when something already exists
-
- **Incidents to learn from? Diagnose first.** The prior question is not what to govern but **which number,
- read before the merge, would have been red?** Walk each post-mortem back to the earliest artefact carrying
- the signal. One would ⇒ that is the metric, and its site is where it could first have been read — including
- the narrow case where you already measure it and the threshold sat past the incident (p99 380 ms against a
- 400 ms gate): recalibrating _is_ the fix. None would ⇒ moving a threshold governs nothing; you are missing a metric, not a number.
-
- **Rules already there, provenance lost, build red? Triage before adding, in this order.**
-
- 1. **Inventory** — a row per rule, marked skipped, red or green — and `git blame` the suppression file and
- the rule definitions: the provenance everyone assumes is lost is usually there.
- 2. **Three eliminating questions** per rule: which characteristic does it defend; can more than one change
- source violate it; would two reviewers agree on its result? Failing any one it leaves — retiring a rule is a legitimate outcome, not a defeat.
- 3. **Route the survivors** into T, C or M; declare every characteristic left with no rule **U**.
- 4. **Under a deadline**, green by a date cannot be the goal, since retiring everything achieves it; the goal is that every remaining red is one somebody chose. Retire and declare first.
-
- If the caller cannot state the characteristic list at all — the normal inherited case — derive a provisional one from the surviving rules, each of which defends something, and send it to `architecture-characteristics`.
-
- ## The decision this skill makes
-
- **For this one characteristic, which governance mode?** Exactly one — though a composite decomposed into
- constituents puts each in its own mode. Nothing here is unconditional, this suite included: one check
- costs maintenance and a suite costs more. **T** automated triggered (commit, PR, release stage, nightly).
- **C** automated continual, against the running system. **M** manual at a cadence: owner, criterion, date,
- recorded verdict — not "we'll look at it sometime". **U** explicitly ungoverned: the name stays on the
- list, governance reads _none_ with an owner and a review date. **This four-mode set, the change-source unit, the triage order above, the price/reversal column below and the delivery paragraph are this skill's construction, not the authors'**; the axes and the quotations are theirs.
-
- | Mode | Objectivity — _would two reviewers agree?_ | Cost — _who pays a red with no defect?_ | Latency | Consequence — _what stops, and who may override?_ | Price even when it is right, and what reverses it |
- | ----- | ------------------------------------------------------- | --------------------------------------------------------- | ------------------ | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
- | **T** | highest — binary by construction | every change waits, including ones that could not fail it | minutes to a day | merge or release blocked; the override is logged | every legitimate change edits the rule too, and the expressible rule stands in for the one that matters. Reverse if its site cannot produce its metric |
- | **C** | high on the number, contested on attribution | an on-call rota; a false alarm wakes someone | seconds to minutes | the documented policy may page, halt rollout, or consume error-budget authority | monitoring cost, noisy attribution, and operational coupling. Reverse or recalibrate when false action outweighs detection value |
- | **M** | depends on criterion, evidence and reviewer calibration | a calendar slot, and a person senior enough to be scarce | one cadence period | a named owner records the verdict and required action | scarce attention and inter-reviewer variance. Reverse when the decision can be made reproducibly from captured evidence |
- | **U** | none claimed — that is the point | nothing now; the full cost of the drift later | unbounded | none. The consequence is that the record says so out loud | the residual is real and nobody watches it; it fails when measurable things get filed under "can't be automated". Reverse on a clean metric |
-
- ## Classifying it tells you where it runs
-
- Axes from _BEA_ ch. 2 (1st ed., 2017, carried forward; whether the 2022 edition changed them is unverified). Independent, not a partition: every check sits somewhere on each. Two more are reminders, not poles: checks are mostly **intentional**, some **emerge** (_absence of a check for X is not evidence X is fine_), and **domain-specific** ones exist only for your business and its regulator.
-
- | Axis | Poles | What the position buys you |
- | ------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------ |
- | **atomic ↔ holistic** | one aspect, one context ↔ several aspects interacting, shared context | holistic catches the cache that fixes scalability and breaks freshness |
- | **triggered ↔ continual** | fires on an event ↔ constant verification in production | the book says _continual_; the Radar and everyone else say _continuous_ |
- | **static ↔ dynamic** | fixed pass/fail ↔ the acceptable value moves with context | a delta threshold survives traffic growth; an absolute one is a promise |
- | **automated ↔ manual** | runs itself ↔ a named human verdict against a written criterion | **objective ≠ automated** — a legal sign-off with a criterion is both |
- | **temporal** | fires because time passed, not because code changed | certificate expiry, EOL runtimes, the "break upon upgrade" backport test |
-
- Placement rule: **the earlier it runs, the more binary it must be** — a dynamic threshold on a PR produces
- arguments, a binary one on a monitor produces 3 a.m. pages, a trailing metric cannot gate a PR at all.
- Placement table and the four legitimate reasons a check stays manual: `references/catalogue.md`.
-
- ## Drivers for encoding a rule, and for leaving it to judgement
-
- | Push toward encoding | Push back toward judgement |
- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
- | Cheap to avoid while the code is written, costly to unwind once others depend on it | The rule you can express is not the one you mean; enforce it and you govern the expressible |
- | It has happened once already and review did not catch it | The result needs interpretation: a red starts an argument rather than ending one |
- | More than one independent change source, no shared reviewer | Its site cannot reliably produce its metric, and it is the largest test you own |
- | A regulator or a contract will ask for dated evidence | Ford: rules nobody understands produce _"an antagonistic, a police state"_ and get routed around |
-
- ## The words this displaces — one test separates them, and **governed ≠ measured**
-
- | Term | What it actually is | Relation |
- | --------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
- | **Unit test** | a code unit's behaviour against a domain expectation | Same harness, different subject: fitness functions measure the -ilities, not behaviour (Ford, 2025) |
- | **Architecture test** | executable assertion over structural or runtime architectural properties | A common subset, often atomic/static/triggered but not necessarily: contract, resilience and topology checks can be dynamic or holistic. `architecture-testing` |
- | **Quality gate** | a bundle of pass/fail conditions at one pipeline stage | A delivery mechanism for the atomic/static/triggered ones. Every quality gate is a set of these; most cannot sit in one. `quality-gates` |
- | **SLO** | a target value or range for an SLI (the SLI is the metric, so not yet one) | A continual + holistic + dynamic fitness function **iff wired to a consequence** — a budget freezing deploys. On a dashboard, a metric. `slo-and-alerting` |
- | **SLA** | a contract with users, carrying consequences | Usually motivates internal fitness functions with safety margin. The contractual measure itself can be governed, but waiting for breach leaves no response headroom |
- | **Metric** | a number with no threshold and no consequence | The gap is exactly those three missing clauses — threshold, site, consequence |
-
- ## Fitness functions
-
- The subject, not a mirror of it. Every entry takes this shape, its threshold carrying its justification:
-
- ```text
- Characteristic Security — implicit-and-critical on ADR-021; several hundred transitive dependencies.
- Metric Highest CVSS among resolved dependencies, plus the count matching the CISA Known Exploited Vulnerabilities catalogue (KEV).
- Tool OWASP dependency-check, Trivy or Grype — replaceable; currency checked by the research brief on 2026-08-27, not by this skill. Confirm before depending on one.
- Threshold The score your own remediation policy already commits to fixing inside a stated window —
- borrowed, not chosen: "high and above inside 14 days" means no build may pass a high on
- day zero. Plus zero KEV entries at any score: that list is exploitation evidence, not severity. The trap is the shipped default: failBuildOnCVSS is 11 on a 0-10 scale, so an unconfigured install can never fail.
- Site The PR on the resolved graph, and nightly on the released artefact — the CVE feed moves without your code, so that one is temporal.
- Consequence Merge blocked; nightly opens a ticket due inside that window, failBuildOnUnusedSuppressionRule on so a dead suppression also fails.
- ```
-
- **When one goes red** there are three legitimate outcomes: fix the code; change the check deliberately, with
- a recorded reason; retire it. Not "skip it for now", and not a baseline mistaken for a ratchet —
- `FreezingArchRule` fails only on _new_ violations and **does not enforce that the count falls**. The
- valuable red is two checks contradicting each other — Parsons: _"when two fitness functions objectively
- contradict each other, then we have to stop with that illusion"_ that all are achievable at once. Ownership sits _"as close as possible to where the problem is"_; a rule its own team cannot change is a straitjacket.
-
- ## What cannot be governed, and how to say so
-
- Subjectivity disqualifies more than teams admit. _"Be maintainable"_ and _"good performance"_ are not
- fitness functions (Ford 2022; Parsons 2025); cyclomatic complexity under a limit is. **But operationalising
- is not governing** — complexity is a proxy, the residual ungoverned whether you say so or not.
- Composites decompose and the composite does not: agility = modularity + testability + deployability, all
- three measurable, agility still not. Maintainability is the one people arrive with, and
- `references/catalogue.md` works it through: five constituents, the row governing each, the residual none see. The deliverable is that decomposition, a check per constituent, **and a written statement of
- what they do not cover**. Four things deterministic checks cannot see (Mahato, Sieczkowski & Kuppusamy,
- InfoQ, 17 Aug 2026): **boundary fidelity**, semantic coupling violating no stated rule; **semantic contract
- drift**, an API staying compatible while ceasing to express the right domain concept; **workflow coupling**, paths no dependency graph shows; **stale ADR assumptions**. So: every change passes every rule while the set of changes drifts from the intent.
-
- **Declaring it ungoverned.** The characteristic stays on the list; its register entry reads `governance:
- none`, with an owner, a review date and one sentence naming what is at risk. No source states this as a
- practice; it is the only construction surviving the objectivity test without pretending. Run
- `scripts/check-governance-register.mjs` over that register nightly — it fails an entry claiming governance with no consequence, or ungoverned with no owner or a lapsed review date.
-
- ## Failure signature
+ An architectural fitness function assesses a stated architectural property. The
+ [Thoughtworks definition](https://www.thoughtworks.com/radar/techniques/architectural-fitness-function)
+ includes tests, metrics and monitors; it does not require every assessment to block delivery.
+ This skill adds the governance decision: who interprets the result, when, and what action follows.
+ An advisory check can be useful; a configured gate is not proof that the intended property holds.
- | Pattern | 18 months on | Earliest detectable symptom |
- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
- | **It shipped unable to fail** | A vulnerability report generated on every build for a year, never once red, everyone believing security is governed, `failBuildOnCVSS` still at its default of 11 on a 0-10 scale | Prove the negative path with a safe fixture. A check may legitimately stay green because it prevents defects; lack of a controlled failing test leaves that unknown |
- | **The pawl nobody pulled** | A frozen violation store committed 18 months ago, the same size, refrozen twice. The rule is documentation with a build step attached | Nobody can state the baseline number without opening the file, and nobody plots it |
- | **Every change green, the design gone** | Boundary fidelity and workflow coupling eroded one legal change at a time; the green pipeline was read as architectural health, a stronger claim than it can support | A new joiner's model of the boundaries comes from the code and differs from the ADR |
- | **Trained to re-run** | The holistic checks are re-run until they pass. Google (17 Apr 2017, ~4.2M tests) found flakiness rises with test size; a commenter datum there: a stable test turning flaky was a real bug about 1 time in 6 | A re-run in the merge log with no accompanying code change |
+ The governance method has no Java baseline and ships no executable Java examples. When a control
+ depends on Java tooling, inspect the project's compiler release/toolchains, resolved tool versions,
+ test runner and CI/runtime JDKs before choosing it. Applying this skill does not authorize upgrades,
+ preview features or new dependencies; keep unsupported tool choices conditional.
- ## How to record it
+ ## Workflow
- ```text
- ADR-023 Governing the order-intake quantum's driving characteristics
- Context Driving list (ADR-021): elasticity, availability, deployability; security implicit-and-
- critical. Four independent change sources merge here, two outside the team.
- Decision Security -> T (above). Availability -> C: the 99.9% SLO already promised to customers, wired
- to a deploy freeze when the budget is spent; without that freeze it was a dashboard for two
- years. Elasticity -> T nightly, not the PR: it needs a load generator and a warm autoscaler.
- Deployability -> M, monthly, never a gate because it trails.
- Consequences One nightly environment, one rota, the wait every change pays. Maintainability is NOT governed: its five constituents are, the residual is accepted. Owner: the tech lead.
- Compliance FF-04, FF-06, FF-11, FF-14 and one ungoverned entry, in the register the nightly script checks.
- Review 2027-02-01, then annually — BEA ch. 2: "at least once a year".
- ```
+ 1. **Establish the promise and evidence.** Obtain the characteristic/scenario, protected scope,
+ acceptance policy and owner. Inspect existing rules, pipeline wiring, suppressions, recent
+ verdicts and relevant incidents. If the characteristic or policy is unknown, record a
+ provisional interpretation and ask for the missing decision; do not invent a threshold or
+ retire a check because its original author is unavailable.
+ 2. **Triage inherited checks.** For each, record enabled/skipped state, evidence actually
+ collected, protected property, observed signal/noise and response. Use history to recover
+ rationale. For an escaped incident, distinguish missing coverage, wrong threshold, stale or
+ absent data, bypassed execution and ignored results. An incident alone does not prove that
+ tightening a threshold fixes the problem; name a replay or fixture that could confirm it.
+ 3. **Define an evaluable contract.** Specify input population, scope/window, metric or rubric,
+ threshold and justification, sampling/uncertainty, and what counts as pass, violation or
+ inconclusive. Missing data, tool failure, no matching classes and an empty scan must not
+ silently count as success. If evidence is unavailable, continue with a conditional design
+ and list the validation still needed.
+ 4. **Choose placement and response.** Read [catalogue.md](references/catalogue.md) when choosing
+ a measurement or execution site. Pick the earliest site that can produce representative
+ evidence at acceptable cost; combine PR, scheduled, runtime and manual checks where needed.
+ Specify owner, detection/response time, action, exception authority and review trigger.
+ 5. **State coverage and gaps.** Read [ungoverned.md](references/ungoverned.md) for composites,
+ judgement-based checks or uncovered concerns. Multiple controls may protect one characteristic;
+ one control may protect several. A single contributor still benefits from controls against
+ costly errors and external drift. No contributor-count rule determines whether a check stays.
+ 6. **Test the control and hand off.** Exercise known passing, violating and unavailable-evidence
+ cases safely. Verify the actual response path: nonzero exit propagated to the gate, alert
+ routed to an owner, or manual verdict recorded with follow-up. Record what was executed.
+ Delegate application test implementation to `architecture-testing` and rollout/baseline
+ integration to `quality-gates`.
- **Handing it back.** Whoever funds this asks two questions, neither about taxonomy. _What does it cost?_ —
- one nightly environment, one rota, and the wait every change pays; give the wait in minutes. _What are we still exposed to?_ — read the ungoverned entries aloud: that list is the answer, green checks are not. Say _a check that stops something_ for fitness function, _we measure it and nothing happens_ for a dashboard, _nobody watches this, and here is who reconsiders_ for ungoverned.
+ ## Decision rules
- ## Honest standing
+ - Distinguish an assessment from its consequence. A result may trigger review, repair work,
+ rollout hold or an authorized exception. Do not label every SLO a dynamic/holistic gate or
+ every quality gate an architectural fitness function.
+ - Automated does not mean deterministic; manual does not mean arbitrary. Calibrate noisy
+ measurements and human rubrics before attaching irreversible consequences.
+ - Green evidence covers only the stated population and property. A dependency rule cannot
+ prove domain boundaries are appropriate; a vulnerability scan cannot prove security.
+ - Fix a violation, correct a defective check, or record an authorized, scoped exception with
+ owner, expiry and compensating action. Retire only with a reason and the resulting gap or
+ replacement documented. Re-running until green and silently refreezing are not remediation.
+ - When checks conflict, compare their scenarios, assumptions and required outcomes. Route the
+ design trade-off to `architecture-trade-off-analysis`; do not relax whichever check is easier.
+ - Distinguish no-new-violations from required debt reduction. A stable baseline can satisfy the
+ former indefinitely; a shrinking deadline needs a separate policy and measurement.
- **No study shows that fitness functions improve outcomes** — no controlled study, no cohort comparison, no
- survey isolating the practice. Adjacent evidence supports the problem and the characteristic, never the
- mechanism: Li, Liang & Avgeriou (2023) mined 606 violation-related comments from 21,583 code-review comments
- across four OpenStack and Qt projects, showing erosion is real and acted on; DORA puts loose coupling among the strongest predictors of delivery performance — the property, not its preservation. Claiming measured benefit is lying.
+ ## Deliverable and reusable checker
- **The live disagreement, both sides.** _Rebranding_: the proponents' own Radar text says a fitness function
- _"may encompass existing verification criteria, such as unit testing, metrics, monitors, and so on"_, and
- Kubowicz (nexocode, 14 Mar 2022) reads ArchUnit as a flexible linter with a ceiling where Java's type erasure
- makes some legitimate rules inexpressible. _Genuinely new_: Ford says the subject is new — architectural capabilities, not business behaviour; Parsons that it is the objectivity criterion plus an owner and a cadence. Both predict the same practice; take neither.
+ For a small review: evidence, defect/gap, consequence, proposed adjustment and validation.
+ For a new control: property/scope, metric or rubric, justified threshold, evidence requirements,
+ site/cadence, response/exception policy, owner and known limits. Include execution cost and
+ unverified assumptions where material.
- ## References
+ If a JSON governance register is used, follow [ungoverned.md](references/ungoverned.md) and run
+ `node scripts/check-governance-register.mjs <register.json>` from this skill's directory.
+ Run on register changes and on a schedule. The checker validates metadata, not actual check
+ execution, coverage or organizational approval. Its test command is documented in that reference.
- - [Catalogue](references/catalogue.md) — metric, threshold shape, site and classification per characteristic, the placement table, dated tool status. Read when choosing a metric and a site.
- - [What cannot be governed](references/ungoverned.md) — decomposition procedure, judgement-bound
- categories, the register schema the script reads. Read before declaring anything ungoverned.
- - [Disagreements and evidence](references/disagreements-and-evidence.md) — both disagreements in full,
- the maintenance-cost question, the evidence table. Read when someone calls the practice proven.
+ For contested benefit claims or behavioral evaluation of this skill, read
+ [disagreements-and-evidence.md](references/disagreements-and-evidence.md). Do not present written
+ cases or checker unit tests as measured improvement in an agent's decisions.