<!-- Starter mirror of a real, mature CLAUDE.md — the portable engineering method (Part A) plus the
     SHAPE of a project rule index (Part B), with the source project's specific rules stripped out. This
     is a MENU: adopt the Part A principles as-is, then write your own Part B. Companion to the
     agent-governance-mechanisms catalogue — many principles map to a control writeup there. -->

# CLAUDE.md — <Project>

This is a **starter** — the governance half of a real, mature CLAUDE.md from an **agent-team-as-team**
codebase (most code is written by dispatched AI agents; the discipline below exists to make that safe at
scale). It's a menu: adopt the Part A principles as-is, then fill Part B with your own project rules.

This file has two parts:

- **Part A — Davis AI-First Engineering Method.** Portable principles for AI-collaborative engineering.
  Apply on every touch; they are about *how to make choices that fit an agent-collaborative codebase*,
  independent of any domain. Adopt these as-is.
- **Part B — Project Reference (write your own).** In the source project this is a stable, numbered index
  of project-specific rules plus the concrete reference (CLI, deploy, architecture, testing). None of it
  transfers — here Part B is stripped to its *shape* + the test for what earns a spot + one worked
  example. Fill it with your own rules.

**Reading order:** Part A is the durable, portable front-matter (Tier-1 read for orchestrators + code
agents). Part B is the reference you build up per-project.

---

# Part A — Davis AI-First Engineering Method

**Copyright © 2026 James C. Davis, PhD (davisjam@purdue.edu).**
*Licensed under the MIT License — free to use, modify, and redistribute
(including commercially), provided this copyright and permission notice are
retained. Full terms in the LICENSE file distributed with this catalogue.*

The portable **method** behind this catalogue: principles for AI-collaborative software engineering,
independent of any domain.

They map onto the governance view the catalogue teaches — every mechanism is either an **architecture**
that makes a failure impossible by construction, or a **control** that observes and guards against one it
can't prevent. The standard engineering playbook (types, tests, DRY, state machines, lints, docs) appears
here *as* those mechanisms, not re-taught.

Four groups:

- **[The governance view](#a1--the-governance-view) (A.1)** — frames the method.
- **[Architecture](#a2--architecture-make-the-failure-impossible-by-construction) (A.2)** and
  **[Controls](#a3--controls-observe-and-guard-what-you-cant-prevent) (A.3)** — the two mechanism kinds.
- **[Operating the method](#a4--operating-the-method) (A.4)** — the working discipline that wields them.

Each principle is the crisp statement + the WHY. Many are also enforced, in the source project, as a
numbered rule plus a lint or gate — adopt the principle, and wire your own enforcement.

## A.1 — The governance view

The frame the rest of the method hangs on: what governance is, how the standard playbook maps into it, and
how to choose and size mechanisms.

### A.1.1. Governance as a method — three complementary targets

Governance is not one thing. A governance **mechanism** is either an *architecture* that makes a failure
impossible by construction, or a *control* that fires on a violation — a lint, gate, validator, regression
/ property / fuzz test, conformance check, or observability assertion. Either way the organizing move is
the same: *convert a recurring failure into a mechanism rather than re-inspect for it*, so a failure
caught once is prevented on every later agent without re-inspection. What makes governance a *method*
rather than a pile of checks is that every mechanism governs one of **three complementary targets**, and a
mature system covers all three:

- **(a) Agent** — the fleet and the substrate that *produces* work. *e.g.* brief-linting, role-typed
  dispatch, the pre-commit → merge-train gate staircase, agent-registry + lifecycle observability.
- **(b) Models-bridge** — the typed models the fleet reasons *through* and governs the codebase *from*
  (a limited slice — config, docs, IPC contracts — is generated from them too). *e.g.* a component/zone
  model, a service-flow model, drift/parity gates. This is how a
  context-*bounded* agent operates a context-*exceeding* codebase — meta-sync keeps the map equal to the
  territory, or the bridge lies.
- **(c) Product** — the shipped artifact. *e.g.* canonical typed models held by ban-lints,
  content-fidelity validation, a regression-test onion, per-mutator provenance stamps, a bounded repair
  vocabulary.

Each target is governed the same way — as a design pattern that holds the *cost of a failure within
bounds*. The axis that most clarifies any single mechanism is **soft** (probabilistic — aims an agent,
can't block) vs. **hard** (deterministic — holds the line regardless of agent cooperation): guidance
*aims*, machinery *holds*.

The worked census — every mechanism by target, family, form, and enforcement, with a full writeup per
concept named above — is this catalogue: **https://davisjam.github.io/agent-governance-mechanisms/**

### A.1.2. Complement competence — map the playbook to the failures it governs

Assume the engineer — human or agent — already knows the craft: how to write a test, factor a module, cut
a duplication, pick a data structure. This method does not re-teach that playbook; it shows **how each
familiar practice fits the governance view** — as an *architecture* that makes a failure impossible or a
*control* that catches it. The value is the map from failure mode to mechanism, not the practice itself.
When a failure recurs, name the class and point to the mechanism that governs it; skip the lecture the
reader could give you. A few standing maps:

- **Flakiness** → nondeterminism (a race, shared state, real I/O behind a fake): a *control* —
  dynamics-aimed tests (→ A.3.4, A.2.10) — never a blanket retry.
- **Duplication that drifts** → an *architecture*: extract on the second site (→ A.2.5).
- **Tangled responsibility** → an *architecture*: decompose along the types (→ A.2.2, A.2.4).
- **Reinventing a solved problem** → reach for a canonical exemplar (→ A.2.8).
- **Silent degradation** → a *control*: never-silent-catch, fail loud (→ A.3.3).

The catalogue entries are this map at scale — each names the failure it kills and whether it *prevents*
(architecture) or *catches* (control). Add to the map when a failure *recurs*, not when a practice is
merely worth teaching.

### A.1.3. Right-size the fix — architecture-first, defense-in-depth

Over- and under-engineering are symmetric failures: a sweeping redesign for a one-off
is as wrong as a hacky patch over a structural flaw. Aim for the middle.

- **Smallest sound change** that closes the *class*, not just the instance —
  proportionate to the failure it prevents.
- **Float larger schemes**, don't reflexively build them — offer the local fix and the
  elaborate one, bias local, let the failure's cost justify the elaborate.
- **Architecture before controls** — prefer making the error impossible to catching it;
  where prevention can't reach, add the control.
- **Belt-and-suspenders** where a failure is costly: do both. Defense-in-depth is a
  feature, not redundancy.

### A.1.4. Proportion governance to the operation — the catalogue is a menu, not a mandate

Governance has a cost: every control taxes every future change and every agent's context budget. The
right amount is not "all of it" — it is the least that holds *your* recurring failures. This method and
its catalogue were distilled from a high-intensity operation (many parallel agents, hundreds of commits a
day); most repos need less than that — though a larger fleet or a higher-stakes domain may need more.
Calibrate to your scale, and treat the catalogue as descriptive — adapt it to fit:

- **Match intensity to pain.** Adopt a control only against a failure you have seen recur — not because
  the catalogue lists it. Default to *skip*; the burden of proof is on adding, not omitting.
- **Small operation → light touch.** One agent or a small team rarely needs the mediators, registries, or
  merge-train machinery; a house-rules doc and a couple of lints may be the whole right answer.
- **Remove what stops earning.** A control that was "fix-once-benefits-all" at scale becomes a
  tax-on-every-change below it; re-audit and delete controls whose failure no longer bites.

The failure mode this guards against is a **tower of governance nobody wants** — controls manufactured
faster than they earn their keep, until the repo is slower and more confusing than the failures it
feared. Grandiosity is a smell; the people most drawn to a governance catalogue are the ones most at risk
of over-building it. (→ A.2.11, A.1.3)

### A.1.5. Reach proactively on the predictive smells — design-time governance

Most governance is failure-driven (A.1.4): default to skip; convert a failure once it *recurs*. But a few
structural traits make a failure class near-certain *before* you've felt it — and for those, reaching for
the mechanism at design time is cheap insurance, not premature. **The trigger is the trait, not the mere
possibility:** if you can't name the near-certain failure the trait creates, it's still YAGNI. Reach when
you see:

- **Concurrency, shared mutable state, or a multi-step mutation that can tear** → a lock/mediator, or make
  the step atomic (transaction / CAS / Lua); walk the T+1…T+N dynamics (→ A.2.10).
- **A stateful lifecycle** (states + transitions) → an explicit state machine, not scattered flags (→ A.2.3).
- **The second copy of the same logic** → unify now, on the second site (→ A.2.5).
- **A raw seam to a powerful resource** (a query language, a subprocess, the filesystem, a format library)
  → one typed seam + a ban-lint on the raw path; a typed signature can make the bug class *unrepresentable*
  (→ A.2.7).
- **The same fact re-derived or hardcoded in more than one place → model it.** Name it once as a typed
  source of truth the tools query, instead of restating it. Two things are worth modeling: **the world**
  (domain state, config, statuses, entities hardcoded across files) and **the codebase itself** (its own
  structure — ownership, zones, seams — re-analyzed by each tool). Model whichever you keep repeating.
- **Retried / queued / time-delayed consumption** → design the second-order dynamics up front (→ A.2.10).
- **A decision point that changes state on a timer or threshold and emits no structured record of what it
  decided** → emit the signal (inputs, computed value, decision, reason) at design time; a silent
  decision core is a near-certain future un-pinnable RCA (→ A.3.6).
- **Multi-writer mutable state with more than one terminal transition** (a row several code paths can move
  to a final state — cancel, fail, complete — or a cancel/timeout edge crossing a concurrency boundary)
  → enumerate the error edges against each other and make each writer resolve consistently (compare-and-
  swap, not blind write); if a wrong terminal state is costly, prove the enumeration complete (→ A.3.4).
- **A trust boundary** — untrusted input, user content, a cross-service call, a secret, or a broad
  capability → validate / escape at the boundary, externalize secrets, grant least privilege.
- **An irreversible op** (delete, overwrite, migrate, force-push) → a guard, a dry-run, or a backup.
- **An invariant that lives only in prose or a head** → encode it + a test that walks it (→ A.3.5).
- **A hot path doing per-item what a bulk, cached, or incremental op could do** (N+1, unbounded fan-out,
  recompute-what-you-could-reuse) → batch it, bound it, make it incremental.
- **An advisory "remember to…"** → make it a hard gate; guidance you must remember rots. A rule about the
  *code* → a lint (→ A.3.1); a step the *operator's own loop* keeps skipping (end-of-turn, context
  compaction, session-start, before-an-action) → a lifecycle hook (→ A.3.7).
- **A design selecting a niche tool / DSL / library over a mainstream alternative, unweighed** → surface
  training-data density as a tiebreaker; the out-of-distribution tool gets re-derived and mis-derived by
  every future agent (→ A.2.8a). A heuristic to raise, not a veto.
- **A control you're about to place** → name its load-bearing *terms* (the nouns the rule is about), then
  put it at the *lowest* layer whose native vocabulary already names them — not higher (re-derives
  vocabulary → drift + false positives) nor below the policy's semantics (→ A.1.6).

These are the *named exceptions* to default-skip — not a license to govern everything. Everything not on
this list stays failure-driven; this is the design-time complement to A.1.2 (which maps a failure to its
mechanism *after* it recurs).

### A.1.6. Place the control at the right layer — the semantic gap has a floor *and* a ceiling

Once you decide to convert a failure into a control, *where* you put it is a second choice — and the
mechanisms sit at different **semantic levels**, the level of meaning at which each can *reason*. A git
pre-commit hook sees a syntactic diff; a reasoning hook sees the diff *plus* a model's judgment; a
whole-worktree (N-of-N) check sees the change as one unit; an Epic definition-of-done sees it against its
*design intent* and the models. Placement is bracketed — a **floor** below which a control can't work and a
**ceiling** above which it rots:

- **Floor — don't place it too low to *express* the policy (the *semantic gap*).** A mechanism below the
  policy's semantics can't name what the rule is about: ask a syntactic hook *"does this change warrant a
  test?"* and the gap is unbridgeable — noise or nothing. (From systems + security: VM introspection,
  firewalls, and access control all fail when enforcement sits below the policy's semantics.)
- **Ceiling — don't place it *higher* than the lowest layer whose native vocabulary already *names* the
  policy's terms.** A control above that layer **re-derives** vocabulary a lower layer already models — a
  regex re-deriving what a parser exposes, a lint string-matching identifiers a typed query already types —
  and re-derived vocabulary breeds false positives and drift (→ A.2.9 regex parser-first; → A.2.8 adopt the
  canonical schema — the same reflexes, applied to *placement*).

**The rule, in one line: place the check at the *lowest* mechanism whose native vocabulary names the
policy's load-bearing terms — which is never below the policy's semantics.** A trailer-present check belongs
at the cheap syntactic hook; *"does this diff warrant a test or doc?"* at a reasoning hook or the N-of-N
check; *"did this Epic deliver its promise?"* at the definition-of-done, where intent and the models are in
view. Calibrating placement is a *judgment* — the lowest-naming-layer isn't mechanically decidable — so it
is a design-time reflex (→ A.1.5), not a lint. (→ A.3.7 lifecycle hooks — the mechanism menu; → A.1.3
right-size — the sibling axis of *how much*, where this is *at what layer*.)

## A.2 — Architecture: make the failure impossible by construction

The first-choice mechanism. Shape the system so the failure class cannot be represented — a typed model
with one sanctioned seam, a state that can't be written wrongly. Prefer these to any control that merely
catches the failure after it happens (→ A.1.3).

### A.2.1. Implementation is cheap; architecture is expensive

Prefer the right design over the faster-but-compromised one. Implementation
is a one-time cost; compromised architecture compounds in maintenance,
agent-confusion, and drift. In an agent-collaborative codebase this asymmetry
is sharper than usual: a bad shape confuses every future agent that reads it,
and substantial refactoring is nearly free (dispatch an agent), so there is
almost never a reason to enshrine a compromise. Corollary: **substantial
refactoring is "free" and drives a recurring audit cadence.**

### A.2.2. Types are how you name shapes; type-in-place before decomposing

Architecture is a structure of shapes; types are how you name them. Types
reveal architecture that primitive-passing leaves anonymous. When decomposing:
(1) annotate the types in-place; (2) let the types become the cross-module
contract; (3) THEN move the typed cluster. Don't decompose what you haven't
yet typed — the types reveal the seam. New Python lands strict-typed; new
frontend lands as TypeScript.

### A.2.3. Explicit models, states, and policies over implicit ones

Name the thing, encode it in types, write a test that walks the encoded
structure. State machines beat scattered counter increments; typed enums beat
magic strings; declared coverage tiers beat binary "covered" claims. Implicit
invariants are invisible to future auditors (human or agent) and rot silently
when surrounding code shifts. This is why job lifecycles are better modelled as
explicit state-machine transition tables than as ad-hoc status increments.

### A.2.4. Class-vs-module shape; single responsibility; extract on the second site

The decomposition default is a module of free functions only for *stateless*
clusters. For a state-bearing cluster (≥2 mutable module-private vars shared
across exported functions, a state machine, or a long-lived cache/handle),
extract a **class** — state wants an owner. Give each unit **one responsibility**:
a module or class that owns two unrelated jobs is two seams wearing one name, and
every future agent has to re-discover the split before it can touch either. And
extract the shared helper on the **second** site, not the third; two files with
the same logic in one PR is the extract-now signal.

### A.2.5. Unify for defect-class consolidation, not just capability

Fix-once-benefits-all is the core affordance — capability parity is
sufficient justification to unify two parallel implementations; you do not
need the merged path to be *more* capable. When two sites share logic, extract
a shared helper — **on the second site, not the third** (DRY-drift hazard).
When unification also unlocks new capability, split the commit: consolidation
(correctness) separate from capability (feature).

### A.2.6. Update call sites; don't preserve legacy shims

When a refactor exposes a cleaner surface, migrate ALL call sites in the same
change. No delegating shim "for backwards compatibility" — compatibility shims
compound into an ongoing two-paths tax that every future agent must reason
about.

### A.2.7. Uniformity over fit — one codebase-wide pattern beats a locally-better bespoke one

Prefer a single consistent approach applied everywhere over a cleverer solution
tuned to one site. In an agent-fleet codebase this trades a small local-optimum
loss for a large system-wide win: a uniform pattern an agent has already seen
200× is applied correctly on reflex, while a bespoke one — however elegant — must
be re-derived from scratch by every future agent that meets it, and each
re-derivation is a chance to get it subtly wrong. Uniformity lowers
agent-confusion and defect *variance* more than local optimization raises
capability. This is the principle behind single-canonical-library, sole-seam, and
one-walker-per-tree disciplines: the win is not that any
one library or model is the best conceivable tool, but that there is exactly
*one* of them, so a fix or a constraint applied once holds everywhere. Deviate
only when a site has a genuine, named reason the uniform pattern cannot serve —
not merely because a bespoke shape would be marginally nicer here.

### A.2.8. Genre check before invent; reach for canonical exemplars

Before proposing a new abstraction, schema, or tool: (1) what is the genre?
(2) who is the canonical best-in-class? (3) can we adopt their schema even if
we skip their runtime? **Adopt the schema even when the runtime is overkill**
— you inherit hard-won constraints at naming-convention cost. And prefer a
single source of truth wherever possible: a stable lint that reads meta-files
at lint-time beats codegen-from-spec beats N hand-rolled lints (each step
loses a drift hazard).

To answer "who is best-in-class," recall the field's most-scrutinized production
systems — for a coding agent the name *is* the retrieval key ("how does Kafka
partition?" recalls more than "how should I shard a queue?"). Reservoirs to jog
memory (not exhaustive): the Apache Software Foundation, the Linux Foundation /
CNCF, Eclipse, GNU; and by genre — streaming/queues:
Kafka, RabbitMQ · orchestration: Kubernetes · relational DBs: PostgreSQL, SQLite
· caches/KV: Redis · web servers/proxies: nginx, Envoy · version control: Git ·
build: Bazel · search: Lucene / Elasticsearch · observability: Prometheus,
OpenTelemetry. Treat these as prior art to adapt, not designs to reinvent.

### A.2.8a. Training-data density is a first-class tool-selection factor

When choosing between a locally-better niche tool and a widely-adopted
mainstream one (a bespoke DSL vs. Rego/OPA, an obscure library vs. a mainstream
framework), weigh that agents produce more reliable output for tools the
training corpus has seen more of. The niche tool is out-of-distribution: every
future agent that meets it re-derives it from thinner evidence, and mis-derives
it more often. This is the agent-era corollary to
[Linus's Law](https://en.wikipedia.org/wiki/Linus%27s_law): with agents, prefer
the thing many eyes — and thus the corpus — have already seen. A **heuristic,
not a mandate** (a genuinely-better niche tool still wins on a large enough
capability gap; no reward for maximizing mainstream-ness). It complements
**uniformity over fit (→ A.2.7)** on a different axis: A.2.7 lowers *intra-repo*
variance; this lowers *agent-error* variance. Pair it with the genre check
(→ A.2.8) as the tiebreaker once two candidates clear best-in-class. The factor
is invisible in the code, so it must be named for an agent to weigh it.

### A.2.9. Regex policy — parser-first

Regex is acceptable for genuinely simple string matching (literal patterns,
fixed prefixes/suffixes, enum values). For anything that parses semantic
structure, reach for the real parser / walker — content streams, JSON from
LLM output, source code, and document tree traversal each have a canonical
parser. Catastrophic backtracking and "regex that was subtly wrong for months"
are the motivators. (The catalogue ships a runnable example lint for this — see
the governance-lint example.)

### A.2.10. Reason about second-order effects and dynamics

A first-order design ("when X happens, do Y") is often correct in isolation
but produces pathological dynamics under repetition, concurrency, or stale
state. Always walk through: what happens at tick T+1, T+10, T+100? What if N
components do this simultaneously? What if state drifts between dispatch and
consumption? For any new substrate with repetition, concurrency, or
time-delayed consumption, write an explicit "second-order dynamics" section in
the design doc. **Dynamics-aimed tests find the real defects** — distributed
bugs live in driving-conditions and cross-component dynamics, not in static
structure; a strong-but-static unit suite will miss them.

### A.2.11. Essence vs. accident — attack accidental complexity; budget for essential

Two kinds of complexity, handled oppositely (Brooks' "No Silver Bullet"):

- **Essential** — the irreducible complexity of the problem and the structures that solve it: the domain
  rules you're paid to get right, *plus* the inherent difficulty of the abstractions, state, and
  interfaces themselves (a consensus protocol has trivial "requirements" yet enormous essential
  complexity). No tool erases it. **Budget** for it — don't pretend a cleverer abstraction makes it
  vanish; mis-labeling it as accidental produces leaky abstractions that cost more than the complexity
  they hid.
- **Accidental** — introduced by our own tooling and choices: parallel implementations, primitive-passing
  that hides shapes, hand-built argv, scattered state, doc↔code drift. **Attack** it — this is the
  complexity the substrate keeps removing (unification for defect-class consolidation, typed seams, single
  sources of truth). A removal *stays* gone only once a control pins it; otherwise it re-accretes through
  drift — which is why a removal graduates into a lint.

The test before any big refactor: are you *reducing* accidental complexity, or just *relocating*
essential complexity behind a prettier name?

### A.2.12. Reprice the paradigm when in-paradigm optimization keeps hitting its own ceiling

Every architecture has a shape of pain — there is no free lunch, only a different lunch. Most
optimization stays *within* the paradigm: keep the substrate, tune its dials, squeeze out the cost.
That is right until it keeps hitting the paradigm's *own* ceiling — the pain no dial removes because it
is inherent to the shape. A recurring in-paradigm ceiling is the signal to price out a *paradigm
change*, not another tuning pass.

- **Name the ceiling, not the symptom.** An in-paradigm fix that keeps almost-working and then hits
  the same wall from a new angle is diagnostic: the wall belongs to the paradigm, not the
  implementation. (Scaling a fixed cluster down to zero kept running into cold-start and scaler
  complexity — both intrinsic to "we operate the cluster.")
- **Reprice as a measured trade, not an aesthetic.** A paradigm change swaps one lunch for another;
  whether the new bill is smaller is an *experiment* (→ A.4.2), gated on the numbers that decide it —
  not a preference for the newer thing. The prototype that measures the trade is disposable; the number
  it produces is the decision. Name the *specific* tradeoffs the swap makes and assess each against
  evidence — for example:
  - **Cost against latency** — a cheaper idle bill often buys a slower cold path; measure both, not
    only the axis you came for.
  - **Operational simplicity against flexibility** — a managed substrate deletes machinery you
    maintain, at the price of what you can express.
  - **Control against reuse** — a gradient in its own right; see the build-vs-adopt bullet below.
- **This is the essence/accident test at the substrate level (→ A.2.11).** Ask whether the machinery
  the ceiling forces you to keep is *essential* to the problem or *accidental* to the paradigm.
  Machinery that exists only to serve the substrate's shape — a bespoke autoscaler, a fairness queue
  rationing a scarcity the substrate itself created — is accidental, and a paradigm change can delete it
  wholesale. That is a permanent win the in-paradigm optimization could never reach.
- **The build-vs-adopt line moves with the substrate — the more managed it is, the more you adopt.**
  A more-managed substrate is a bargain with a catch: it hands you built-ins (retries, autoscale,
  queueing, identity, telemetry) *and* takes away the room for custom work (no durable state, a
  short-lived constrained runtime). Both point the same way — on the managed end, handrolling what the
  platform provides earns diminishing, then negative, returns. So a move toward it is a mandate to
  *retire* handrolls for platform-native, never to carry them across, and least of all to *add* new
  custom machinery the substrate already offers (handrolling telemetry on the way into serverless is
  exactly backwards). The trade is **reuse for control** — the con-side of the paradigm swap, and the
  posture that pays it well (→ A.2.8 adopt-canonical, A.2.11 accidental complexity).

Reach for this only when an in-paradigm optimization has *recurred* against the same ceiling. A single
hard problem is not a reason to re-platform.

### A.2.13. An architecture change is an X-ray for embedded assumptions — walk it through the models

Changing the architecture — the deployment substrate, the storage engine, the concurrency model —
forces every assumption the old substrate silently carried out into the open. A decision that read as
obviously right *given the old shape* (embed the runtime rather than add a network hop; stash
correctness-carrying state in the fast in-memory sidecar) becomes visibly a *choice* under the new one.
Surfacing and re-deciding those assumptions is a win independent of whether you migrate: the codebase
ends with its substrate assumptions *explicit*, so the next shift is cheaper.

- **The change reveals where the substrate carried a guarantee.** The places that *have* to change are
  precisely where the old substrate had absorbed a semantic guarantee the design never modeled. (A
  pop-from-queue that was atomic *by accident of the in-memory primitive* must become an explicit
  single-consumer claim under a managed queue — the migration forces a latent guarantee into the open.)
  That is not breakage; it is the model getting more truthful. The same X-ray re-decides where
  *computation lives* and *how services talk* once the substrate that made the old answer free is gone.
- **If you have typed models, the change is a bounded walk, not a leap.** Enumerate each modeled
  element and classify it **orthogonal** (unchanged — the model abstracted the substrate correctly) or
  **shifts** (the substrate leaked in). A mismatch is a *localizing diagnostic*: it names exactly where
  to look, and closing it is a model *improvement*, not a rescue. The product-semantic core riding
  through untouched is the map being *validated* against a paradigm change of the territory — the
  deepest dividend of keeping the map equal to the territory (→ the models-bridge target).
- **Start the hunt from the user-journey model and follow the threads.** A component-deep view has a
  blind spot: everything a user touches that is *not* the core pipeline. Walk each journey, and at each
  touchpoint ask "does the change reach here?" — that is how the non-obvious implications surface
  (billing, invoicing, admin views), the ones a pipeline-shaped analysis misses.

**YAGNI governs the whole lens.** Reach for the X-ray only when you are actually contemplating or doing
an architecture change — do not hunt for embedded assumptions in a stable system. And the exhaustive
element-by-element orthogonality pass earns its cost only when a change is live *and* the design keeps
dancing near the substrate boundary; a one-off is not a reason to walk the whole model.

## A.3 — Controls: observe and guard what you can't prevent

Where architecture can't make a failure impossible, catch it: a lint, a gate, a test, a validator that
fires on violation and holds the line. The organizing move — *convert a recurring failure into a control
rather than re-inspect for it* (→ A.1.1).

### A.3.1. Enforce structure with the compiler / static analysis — do not defer

Author the lint or type-check *now*, even when it has zero findings today;
forward-policing IS the value. Code review is not a substitute for static
analysis. **Move audits to lints** whenever the signal is mechanically
detectable — audit signals are expensive, deferrable, and post-hoc; lint
signals are cheap, at-PR, and deterministic. Today's audit finding should
become tomorrow's lint: if a bug is in N>1 files, the right fix shape is "fix
N sites + add a lint," not "fix N sites and wait for the next audit." For a
class-level failure, propose a lint that prevents the class — not just a one-off fix.

### A.3.2. Quality gates — grade on the commodity-lint floor

Every commit should pass the project's standing gates (type-check, tests,
lint, behavior-identity smoke). Gates that catch defects at commit time
prevent ones that surface at review or production time, both of which cost the
user more attention than the gate cost the agent. **Grade the codebase on its
commodity-lint floor** (ruff / eslint / tsc / pyright / Roslyn analyzers), not
on the count of bespoke custom lints — the floor is what a fresh reader can
trust. **Dependency manifests must be complete (SBOM discipline):** every
third-party package the code or the gates use MUST be declared in the matching
manifest, and any out-of-band `pip install` / `npm install` an agent runs MUST
be persisted in the same change — an undeclared tool is invisible to SBOM
retrieval and breaks a fresh checkout's gates.

### A.3.3. Never silent-catch

Every `except` / `catch` must log, re-throw, convert to a domain error, OR
carry an inline comment justifying the swallow. A silent catch turns a
fail-loud bug into a fail-quiet one — the worst failure mode for a pipeline
where "ran successfully but produced garbage" is invisible. This composes with
a **fail-fast** posture: when a dependency is unreachable, fail loudly rather
than degrade silently.

### A.3.4. Testing strategies — reach for the kind that fits the failure

A specific test is a control; the *strategy* is the general means of building one that catches the
*class*, not just the example in front of you. Match strategy to failure mode — all fair game:

- **Property-based** — invariants over generated inputs.
- **Doc-driven** — pin a doc's claims to the code so the two can't drift.
- **Schema-driven** — structural conformance to a typed shape / registry.
- **Fuzz** — adversarial inputs against a stable point in the spec.
- **State-machine coverage** — walk the declared transitions; catch the illegal ones.
- **User-journey** — end-to-end flows over real driving conditions.
- **Dynamics-aimed** — repetition / concurrency / stale-state, where distributed bugs live (→ A.2.10).
- **Error-path enumeration** — walk each *named failure edge* (cancel / timeout / crash / preemption /
  partial-write / concurrent-terminal) and ask: does every participant resolve to a consistent terminal
  state? Sibling to *dynamics-aimed* — that asks "what at T+N under concurrency?", this asks "is each
  error edge's resolution clean?" — and it catches what a happy-path *or* dynamics suite sails past
  (e.g. two different terminal writers racing one row). It presupposes *typed* error edges (you can't
  enumerate string-land); where a wrong terminal state is costly, prove the walk complete with an
  exhaustive state-space check.

Reach for the right *kind*, not one canonical suite; a strong-but-static unit suite misses the dynamics
and error-path ones every time.

### A.3.5. Documentation — the invariants-driven pattern

Subsystem / architecture docs earn their keep through four essential
elements; a doc without them is prose that rots: (1) **a section per real
part** — one section/row per source, stage, module, or entity, mirroring the
actual structure; (2) **invariants with stable IDs** — each invariant a
tagged, testable predicate with a `file:line` cite, and the ID is the join key
that tests and audits cite; (3) **as-built vs design, ⚠️-marked** — call out
where code diverges from design, because the ⚠️ gaps are where the next work
is; (4) **enforcement: invariants → tests** — map each invariant ID to the
test that pins it, or mark it UNTESTED, so the doc *drives* the test backlog.
Design docs encode invariants, not just rationale. (The catalogue ships a
design-doc template starter built on this pattern.)

### A.3.6. Diagnosability-driven observability — an un-pinnable diagnosis is a finding about the signal

When a root-cause analysis **cannot pin the cause from the signal you already have** (logs, events,
traces), treat that inability as a finding in its own right — not a dead end. Add the observability that
*would* have pinned it, so this failure and the ones like it are diagnosable next time **without a
re-run**. This is the runtime analogue of A.3.1's audit→lint reflex: **today's un-pinnable diagnosis
becomes tomorrow's standing signal.** It composes with the fix — close the bug *and* the signal gap —
and never replaces it.

The shape that pays off: a decision point that changes system state — a scaler, a retry, a router, a
gate — emits a **structured, per-decision record** of its inputs, the value it computed, the decision it
took, and why. A later anomaly is then reconstructable from the record alone. Guidance *aims* ("look for
the missing signal"); the emitted signal holds — and a substrate that emits a signal owns it end to end:
whatever emits it also says what healthy looks like and where to look when it isn't.

**And measure one level deeper (Ousterhout).** A signal has a *depth* as well as a presence. Ask what
DECISION the measurement must drive, then instrument one level *below* the surface number, so the data can
**act**, not merely **report**. A metric that only reports is a level too shallow the moment its purpose
is to *change* something: a blended fleet-wide compute cost affords an invoice, but not the engineering
question — *which job, on which service, costs the most, so we know what to optimize* — which needs the
per-service-per-job breakdown underneath. The un-pinnable diagnosis is a finding about the signal's
*presence*; the un-actionable metric is a finding about its *depth*. Same reflex, one level down:
instrument for the decision, not for the surface reading.

**Prefer causation to correlation.** A co-occurrence metric only reports ("a nudge and a fix shared a
session"); a cause-key the actor mints at the moment of action and carries to the effect can act — drive a
pull decision, an ablation, a defensible claim. Where the cause is known when the change is made, stamp it
from a closed taxonomy and assert it at the gate; where it can only be inferred, name the metric `_proxy`
and never reward a rate — the trace exists to explain, not to be optimized.

### A.3.7. Hook the operator's own loop — interpose on the runtime's lifecycle events

Some recurring failures live not in the code an agent writes but in the *loop that drives it* — the
operator (a human, or an orchestrator agent) omitting a step at a predictable moment: ending a turn with
ratified work still queued, compacting context without first writing a hand-off, opening a session
without reading the alert backlog, editing outside the sanctioned worktree. A lint can't reach these —
there's no source artifact to analyze, and the omission happens at runtime. The control is a **lifecycle
hook**: a script the runtime fires deterministically on a named event — turn-stop, pre-compaction,
session-start, before-a-tool-call. It is A.3.1's audit→lint reflex moved from the codebase to the agent
runtime, and the runtime counterpart to the commit-content pre-commit gate — that guards what gets
*written*; this guards what the loop *does*.

A lifecycle hook is neither purely hard nor purely soft — it **splits the two halves of enforcement a
lint fuses**. Its *firing* is hard: the runtime guarantees the hook runs at the event, so the operator
cannot forget to invoke it. Its *payload* is either — a hard **block** that denies the action (a pre-edit
guard refusing a write outside the worktree), or **soft guidance** injected back into the agent's own
context (a stop-hook that re-states "work still queued" and leaves the agent to judge). The reflex case —
*hard delivery of soft guidance* — is the one to understand: it doesn't swap judgment for machinery, it
makes the *aiming* deterministic. A house-rule "remember to…" (→ A.1.5) depends on the agent recalling it
at the right moment and rots; the hook fires that same guidance *exactly* at the decision point, every
time. Guidance still aims (→ A.1.1) — the hook guarantees the aim is taken when it matters.

Right-size it (→ A.1.3): a hook fires on *every* occurrence of its event and can stall the loop, so reach
for one once a soft reflex has demonstrably failed to hold — not on first sight — keep its check cheap,
and make a soft-guidance hook fail-open, so a bug in the hook can't brick the session.

## A.4 — Operating the method

How the agent works the loop day to day: the stance that keeps velocity honest without lifting the gates.

### A.4.1. Autonomy — carry work through; surface only load-bearing decisions

When the user invites autonomy: make good judgments, don't round-trip on
every decision, carry agreed work through to a sensible stopping point, and
surface doubts at the end of a work block rather than at each step. **Rework
is cheaper than waiting.** Make calls inline when they're judgment ("which of
two reasonable shapes?"); surface the decision when it is genuinely
architectural and load-bearing ("should this whole subsystem be reshaped?").
**When uncertain about a load-bearing call — scope, a naming seam, a design
axis — ask the user; do NOT defer the call to a sub-agent.** A fuzzy brief
lets the agent silently answer a narrower question than intended. Autonomy
never lifts the quality gates — speed comes from fewer round-trips, not from
skipping checks.

### A.4.2. Hyper-experimentation — pilot, compare, measure; the prototypes throw away, the learning stays

Ground decisions in data, because in the agentic era data is cheap. Run pilot
studies before wider sweeps; surface 2–3 alternatives before picking; measure
rather than argue — a pilot beats a debate. The discipline that keeps this
from becoming flailing: experiments must be **falsifiable** and grounded in
**ground truth**, **negative results are wins** (a cheap pilot that kills a
bad path saved an expensive build), and you must be willing to be wrong and
**correct the record when the data contradicts you**. The prototype is
disposable; the learning it produces is what you keep.

### A.4.3. Verify factual claims; trust nothing stale

A 30-second `grep` / `wc` / `ls` before quoting a number, a filename, or a
schema fact prevents stale-claim drift — verify brief premises before
dispatching. When reviewing "done" work, **trust nothing at HEAD**: re-run the
gates, pin-tests, and lints yourself; markers and counts rot when sibling
sweeps break the substrate. Agent reports describe *intent*, not *reality* —
verify. This is the central discipline of the final, independent
"trust-nothing" definition-of-done review.

### A.4.4. Destructive-op care

`rm -rf`, overwrite-in-place, force-push, history rewrite: in-repo / scratch
(`/tmp`) is fine without asking; anything outside the repo working tree gets an
explicit ask first, **every time**. Always look before deleting — never remove
a path you did not create or whose contents contradict how it was described.
Destructive `git` on `main` (`reset --hard`, reset to older refs, force-push)
requires explicit user approval — the orchestrator's inline shell has no
worktree backstop, so a flailing reset destroys work permanently. Undo a
landed commit with `revert`, never `reset`.

### A.4.5. Comments and commits earn their place

**Comments** default to none; a comment justifies its existence by explaining
*why* (a non-obvious invariant, a chosen trade-off, a footgun), not by
restating *what* the code does. **Commits** land in reasonable, self-contained
sets with messages that state the intent; agents commit per meaningful step
(never accumulate) and carry a co-author trailer, e.g.
`Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>`.

*Attribution: Part A is a portable engineering method, reusable across projects, governed by the MIT
license at the head of Part A.*

---

# Part B — Project Reference (write your own)

Part B is where the portable method (Part A) meets **your** codebase. In the source project it is a
stable, numbered index of project-specific rules — each cited by number across the code, never
renumbered — followed by the concrete reference (CLI commands, deploy, architecture, library discipline,
testing, the agent-dispatch machinery). None of that content transfers; you write your own. What *does*
transfer is the **shape**, below.

## What earns a spot in this file

CLAUDE.md is loaded into every agent's context, so every rule pays a per-invocation cost. A rule earns
its place only if **all three** hold:

1. **Regression-preventing** — an agent who didn't know the rule, touching code that doesn't look
   related, could accidentally violate it.
2. **Non-derivable from the immediate code** — reading the file being edited wouldn't surface it.
3. **Non-local** — it crosses files / subsystems. A pattern specific to one class belongs as a
   doc-comment on that class, not here.

If a rule fails any of these, route it out: to a subsystem doc, a class doc-comment, or an inline
`WHY:` comment. Every rule here should cross-reference the doc that explains it in full — CLAUDE.md
carries the minimum agent boot context; the referenced doc carries the complete rationale.

**The skill case — cite, don't mirror.** If the depth lives in an *invocable skill* (a hardening skill,
an operating skill, a communicating skill), do **not** copy its content here. A mirrored skill fires ~never
— agents apply the always-loaded copy ambiently and never *invoke* the skill, losing its depth-on-demand
(its typed modes, its on-demand reference, its recurrence gate), while the two copies drift (→ A.2.5). Keep
only the thin, always-on **reflex** in CLAUDE.md, **cite** the skill for the machinery, and add a
**trigger** — a lifecycle hook that pushes "invoke `<skill>`" at the decision point where its structured
mode earns its keep (the reflection-facet / lifecycle-hook controls in the catalogue). It is the
single-source-of-truth move (→ A.9) — but here the copy doesn't merely drift, it *suppresses the skill.*

**Keep the house lexicon living.** The communicating skill (self-communicate) owns a **house lexicon** —
the vocabulary of terms-of-art your prose reuses. Bootstrap it once by walking your codebase (sample the
house-rules doc, design docs, and typed enums / registries), then confirm the terms with the maintainer.
Keep it living: update it whenever you coin a term or notice two words for one idea. A consistent
vocabulary is what lets a control mean the same thing everywhere it is cited.

## The shape of a rule (one worked example)

**Number your rules and never renumber them** — the number becomes a citable namespace ("rule #15")
across the codebase. Each rule is a crisp imperative + the WHY + a pointer to where it's *enforced* (a
lint or gate) or explained in full. For example:

> **1. All `<format>` I/O goes through the typed model, never the raw library.** Read via the model's
> reader; write via its typed mutators. Raw-library constructors are banned — a single sanctioned seam
> means a fix or a constraint applied once holds everywhere (→ A.2.7). Enforced by a sole-seam ban-lint
> on the raw alternative. See the *canonical models & seams* control in the catalogue.

Note the moves: an arrow to the Part A principle it instantiates (`→ A.2.7`), a named enforcement
mechanism (the ban-lint), and a link to the catalogue control that generalises it. A rule without an
enforcement pointer is a hope, not a gate.

## Insert your project's rules here

Add rules as your agents surface recurring failures — each new rule is ideally paired with a lint that
prevents the class from recurring (Part A.3.1 + A.1.1: *convert a recurring failure into a control*).
Common sections a mature Part B also carries, all project-specific: conversation conventions, CLI
commands, deploy discipline, architecture overview, library / dependency discipline, testing tiers, and
the agent-dispatch / orchestration machinery. Grow it deliberately — the "what earns a spot" test above
is what keeps it from bloating into noise every agent has to page through.
