Harness Engineering / Constraint Engineering / design standard

Model the constraint first, then pick the machinery.

Agent reliability work looks like infrastructure. It is domain modeling, and the object it models is a constraint. One constraint carries four independent attributes: whose rule it is, what mechanism carries it, what happens when it fires, and whether a model or a machine decides. Collapse any two and your harness stops traveling. I have no number for how much variance to accept. This page is the apparatus for holding one you pick yourself.

the argument · domain design, not infrastructure. No queues, no wiring, no framework
where it sits · the DevOps area, spanning development and platform, and owned by neither alone
the frame · domain-driven design and object orientation, borrowed on purpose. Section 1 and section 5 carry the mappings
the primitives · about fifty, cataloged in section 12 by family, context and rung
the patterns · 24 harness · 24 factory · 12 human-in-the-loop · 18 anti-patterns
the implementation · wipp, a factory of mine. Private, so this page carries the design rather than a clone URL
what it runs against · three repositories, one of them itself, on a stock agent SDK
what is honest · the band has no published number, including from me. Section 0 says why that is still worth naming
reads alongside · Layers and Promotion (the measured version) · Anatomy of a Charter · Five Guardrails · The Factory
license · CC BY 4.0. Take the model, not the vocabulary
Layer
Whose constraint it is, and therefore who may change it. Org, then team, then project, strongest first.
Rung
Which mechanism carries it. Prose, tool grant, hook, in-harness check, stage gate, CI.
Policy
What happens when it fires. Refuse, ask a human, or record and allow.
Verdict
Who decides. A model reads the work and judges, or code reads it and settles.
Part I

The model

What a constraint is, what it is made of, where it can live, and how it moves. Twelve sections, and no machinery in any of them. Part II catalogs what you build on top.

0 The band

The organization is setting a risk appetite, and calling it a style guide

Businesses already know how to do this. They write a risk appetite, define tolerances, build controls, and keep a register of the exceptions. Agent output needs the same apparatus, because the question is never "is this code correct". It is "how much unreviewed variance will we accept, and where do we spend to narrow it".

org sets the band team holds it project works inside it

Call it a reliability band: the range of agent output an organization will accept without a human reading every line. A wide band is cheap to run and expensive to trust. A narrow one costs a gate at every seam, and the gates are the budget. Nobody argues about the band directly, so the merge queue settles it one pull request at a time.

Constraint engineering is my name for the work of holding that band. Making a model correct is not the goal, because nobody is offering that. The goal is to constrain the model at several layers, with a different strategy at each. You stop tightening when the output lands inside the band often enough to be worth the tokens.

What I cannot give you, and will not invent

I have no number for the band. Neither does anyone I have read. What follows is the apparatus for holding one once you pick it. Where a constraint goes, what makes it good there, and what evidence moves it. Treat the sections on evidence as the part that lets you set a number later, from your own runs rather than from mine.

Push the business analogy one step further, because it predicts the failure. A risk framework dies two ways. People who cannot see the work own the controls, or people who can see it handle the exceptions quietly. Both have exact analogues in a harness, and section 22 covers the role that prevents them.

1 Modeling

Designing an agent is domain modeling, and the machinery is a second job

Two levels sit here, and teams build only one. The conceptual level says what a constraint is, what it is made of, and how it may change. The infrastructure level runs it. Skip the model and every new repository gets a copy of your machinery instead of your design.

conceptual the model infrastructure the runner one survives the other

Start with the test that separates the two levels. Change your agent SDK tomorrow. If your rules survive the change, you have a model. If you rewrite them, you had machinery and called it a design. That is the whole distinction, and it costs a migration to learn the slow way.

The conceptual level answers four questions, and none of them mentions a process or a queue. What is the thing? What attributes does it carry? What is its consistency boundary? How does it change, and who may change it? Answer those and the runner becomes an implementation detail. Skip them and the runner becomes the design.

One more placement, because it decides who is in the room. This domain sits where DevOps sits. It spans development and platform, and it belongs to neither alone. DevOps merged two roles that could not hold a deployment between them. Constraint engineering merges the same two roles, because neither of them can hold a reliability band alone. Section 17 splits the work into sub-disciplines, and section 22 says what each side sees and what each side misses.

one model, several runnersthe model outlives the machinery
flowchart TD
  M["the model · constraint · layer · rung · policy · verdict · family · context · identity"]
  A["a coding agent CLI · charter files, hooks, skills"]
  B["an SDK loop you wrote · predicates in front of every call"]
  C["a delivery pipeline · stages, gates, records"]
  M --> A
  M --> B
  M --> C
  N["swap any runner and the model is unchanged"]
  C --- N
  class M pass
  class A warn
  class B warn
  class C warn
  class N dim

The model in one picture

Below is the whole model as a graph, and every later section is one region of it. Read the arrows as relationships rather than as flow. Section 23 defines each term once, so treat that section as the dictionary and this diagram as the map.

One loop in the graph carries more weight than the rest. Firings and hatch uses become evidence, evidence argues for a move, and a move changes the rung that produces the firings. Cut that loop and the model still looks complete, and it stops learning anything.

the concepts, and what relates themthe evidence loop is the part people cut
flowchart TB
  CON["constraint · the entity"]
  LAYER["layer · whose rule"]
  RUNG["rung · what carries it"]
  POLICY["policy · what happens"]
  VERDICT["verdict · who decides"]
  PRED["predicate · the decision procedure"]
  ESC["escape hatch · the sanctioned deviation"]
  CAP["capability · what the agent can do"]
  SET["setting · budgets and caps"]
  STATE["state · memory and context"]
  EVID["evidence · counts, records, evals"]
  MOVE["promotion or demotion · a pull request"]
  HUMAN["a human"]
  CONTRACT["contract · what was asked"]
  CTX["charter · harness · factory"]

  CON -- "owned by" --> LAYER
  CON -- "carried at" --> RUNG
  CON -- "acts by" --> POLICY
  CON -- "decided by" --> VERDICT
  CON -- "asks" --> PRED
  CON -- "waived by" --> ESC
  RUNG -- "lives in one of" --> CTX
  VERDICT -- "inferential asks a model, deterministic asks" --> PRED
  POLICY -- "ask routes to" --> HUMAN
  CAP -- "withheld at rung 1, so it becomes" --> CON
  SET -- "bounds the turn and the job" --> CTX
  STATE -- "unowned, it becomes a rule nobody wrote" --> CON
  RUNG -- "firings counted as" --> EVID
  ESC -- "uses counted as" --> EVID
  CONTRACT -- "graded against" --> EVID
  HUMAN -- "amends" --> CONTRACT
  EVID -- "argues for" --> MOVE
  MOVE -- "approved by" --> HUMAN
  MOVE -- "changes" --> RUNG
  class CON block
  class RUNG warn
  class VERDICT warn
  class POLICY pass
  class PRED pass
  class EVID pass
  class MOVE block
  class HUMAN warn
  class LAYER dim
  class ESC dim
  class CAP dim
  class SET dim
  class STATE dim
  class CONTRACT dim
  class CTX dim

The mapping, because the problems are not new

I reach for domain-driven design here because I had the machinery working and still could not say what a rule was. The vocabulary is not the point, and section 5 borrows a second frame for a second reason. Use the mapping to test your model, then throw the words away.

the model, in domain-driven design termsborrow the checks, not the vocabulary
In this modelIn DDDWhy the mapping holds
a constraintentityit has an identity that survives a rewrite of its predicate, its rung and its prose
layer, rung, policy, verdictvalue objectsno identity of their own. Compared by value, replaced rather than edited
the predicatespecificationa decision procedure written once and asked of many candidates
a familyaggregateone lifecycle and one consistency boundary. You may not half-apply it
charter, harness, factorybounded contextseach names its own terms, and the dependency between them runs one way
the layer fieldthe context mapit records which context ships the rule, so the harness can travel
lockedinvariantthe one thing a downstream context may not lower
the rule file's fieldsubiquitous languagethe same six words appear in prose, in config, and in the record
the contractaggregate root of a jobeverything about the work hangs off it, and nothing downstream may rewrite it

Non-goals
Not an argument that you should adopt domain-driven design.
Not a claim that agent work is a domain the way billing is a domain.
Not a layered architecture, and not a diagram of your services.

The one check worth running today

Open your rules and look for an identity. A rule that is only a line in a file loses its history the moment you move it or reword it. Then you have no entity, so nothing can be promoted, demoted or counted. Every later section assumes a constraint you can name twice and recognize both times.

2 Four attributes

One constraint carries four independent attributes

Whose rule it is, what mechanism carries it, what happens when it fires, and who decides. Those are four questions with four different answers and, often, four different owners. Model any two as one field and the harness stops traveling.

layer org · team · project rung 0 to 5 policy refuse · ask · warn verdict inferential · deterministic
one rule file, four orthogonal answersthe rung is not the authority
---
description: A broad except says what it is swallowing and why
why: A gate that fails silently on its own bug stops the factory invisibly.
paths: ["workers/**"]
layer: team              # whose rule. Ships with the harness, not the repo
rung: [3d, 4d]          # what carries it. Two boundaries, not two strictnesses
policy: refuse          # what happens. refuse | ask | warn
verdict: deterministic   # who decides. A predicate, not a judge
locked: false            # may a project override it, or only deviate visibly
predicate: predicates/name_the_swallow.py
escape: swallow-ok
---

The four attributes answer different questions, and confusing any two causes a specific failure. Layer says who ships the rule and who may change it. Rung says which mechanism refuses. Policy says whether a firing stops the work, parks it for a human, or only leaves a record. Verdict says whether a model judged the case or code settled it.

I shipped the layer field and then read it nowhere for months. For that whole time a company standard and one repository's local opinion were the same kind of object. So the harness was something you copied rather than something you shared, which is a modeling bug rather than a coding one.

what each collapse costsall four are modeling errors
The collapseWhat it looks likeWhat breaks
layer into rung strong rules live high, weak rules live low authority becomes "how much I care", and nothing travels between repositories
policy into rung warn is modeled as a lower rung a rule you wanted measured is instead unenforced, and the counts look the same
rung into layer the org owns every mechanism a project cannot carry its own rule anywhere, so it routes around all of it
verdict into rung a judged check and a coded check share a rung a rule a model decides looks as reliable as one a predicate decides, and the record cannot tell you which kind failed

Policy deserves one note, because people leave that attribute out. A rule set to ask parks the call and puts a human in the loop. It is honest only at a rung that can hold a call rather than veto it. If your mechanism can only say no, ask becomes a rule that refuses in silence, which is worse than either option.

Verdict is the attribute I added last, and section 5 is where it earns its place. Read it now as a plain fact about the mechanism. Either a model read the work and judged, or code read it and settled. Those two fail in different ways, so the record has to keep them apart.

The design test

Take any rule you enforce today and write down its four answers separately. If you cannot name a layer without naming a rung, you have one attribute where you need four. Your harness is then a thing you copy into repositories rather than a thing that governs them.

3 Three contexts

Charter, harness and factory are three bounded contexts

Charter is the project: what this repository is about. Harness is development: how a turn happens. Factory is delivery: how work ships. Each owns different components, and the dependency between them points one way only.

charter project harness development factory delivery
three contexts, one directionthe harness must run without the factory
flowchart TD
  F["factory · delivery · stage · gate · guard · ordering · record"]
  H["harness · development · prompt · tool · policy · budget · context · phase"]
  C["charter · project · rule · hook · skill · command · agent · predicate"]
  F -- "hands in its own delivery rules" --> H
  H -- "reads what the repository declares" --> C
  C -- "cannot reach upward" --> X["a charter that configured the harness would be a repo governing the fleet"]
  class F block
  class H warn
  class C pass
  class X dim

The direction matters more than the contents. The factory knows about the harness, and the harness must not know about the factory. Point that arrow both ways and the harness stops running on its own. A developer can then no longer ask the only question they have: what do my charter and my rules do to a turn?

That question makes a harness a product rather than a subsystem. Someone working in a repository wants to run one turn, see which rules fired, and see what it cost. They do not want a queue, a worktree or a pull request. If your design cannot serve that, developers build their own, and you get two harnesses that disagree.

What each context owns

components by contexta component in the wrong context is the common defect
ContextAboutComponentsChanges
charterthis project rule · hook · skill · command · agent · predicate · convention constantly
harnesshow work is done prompt · tool · policy · budget · context · phase rarely
factoryhow work is delivered stage · gate · guard · ordering · record very rarely
evalanywhere a measurement, for what no rule can decide with the thing it measures

Those change frequencies are a diagnostic, not a schedule. Proposals should thin out with distance from the project's own code. Most of what goes wrong is something the repository wanted and never said. So a cycle producing three factory changes and no charter ones tells you the distribution is wrong, not that the factory needs work.

The org has opinions at two of these, and the split is not about ownership

A company standard about how code gets written belongs in the harness, because it must reach every turn including a developer's local one. A company standard about how code ships belongs in the factory, at the delivery rungs. Both are org-layer rules. They live in different contexts because they govern different things, not because different people own them.

4 Five families

Five families of component, and each one moves a different way

A family is an aggregate: one lifecycle, one consistency boundary. Give every component the same lifecycle and you will spend months promoting things that have nowhere to go. You will also withhold things that were never capabilities.

constraint escalates capability encapsulated setting tuned evidence calibrated state scoped
the five familiestwo of them have a ladder, and they are different ladders
FamilyPrimitivesLifecycleMoves how
constraint rule · hook · gate · guard · predicate · convention add · improve · remove · migrate · promote · demote up and down a rung
capability tool · skill · command · sub-agent · phase · MCP server add · improve · remove · migrate · encapsulate granted or withheld, and along a second ladder
setting budget · model · policy · ordering · turn cap · thinking level add · improve · remove · migrate a value changes, never a rung
evidence eval · record · log · count · verdict · trace add · improve · remove · migrate recalibrated. It measures, and never refuses
state memory · context · transcript · spec · checkpoint add · improve · remove · migrate derived, or scoped to a layer and a life

Two of those families cause most of the confusion. A capability and a constraint look alike in a config file, because both are entries in a list. They differ in what happens when you remove the entry. Remove a capability and the agent can do less. Remove a constraint and the agent can do more.

A correction to an earlier version of this page

I used to write that a capability has no ladder, because it never refuses anything. The first half of that is right and the second half hid something. A capability does not climb the constraint chain, and it has a chain of its own. Section 5 is that chain. It exists because the question came up: are commands, skills, sub-agents and tool servers the same shape as rules, hooks and gates?

State, which is the family people model last

Memory is the primitive teams reach for first and design last. A fact the system remembers becomes a constraint nobody wrote down. It shapes every later turn, and it has no layer, no owner, no review and no expiry. The default worth holding is derive, don't remember: rebuild what you need from the work record and the repository.

When you do need memory, give it what every other primitive has. A layer, so someone owns it. A scope, so it cannot govern work it never saw. An expiry or a re-derivation, so it cannot outlive the thing it described. Memory without those three is drift with a good reputation.

Context is the other half of this family, and the trade is direct. You pay for everything in the window on every turn, and it crowds out the rules that matter. Section 20 counts that cost as one of the five kinds of rot.

The family test, which takes ten seconds

Remove the component and ask what changed. The agent can do less, so it was a capability. The agent can do more, so it was a constraint. A number moved, so it was a setting. You know less about what happened, so it was evidence. The agent forgot something, so it was state.

5 Two chains

Two chains, one axis: what the model interprets, and what it can only call

Constraints climb from prose to a hook to the harness to the factory. Capabilities climb from a command to a skill to a sub-agent to a tool server. Different families, different ladders, and the same underlying question at every step.

constraints reach and authority capabilities encapsulation both text becomes code

Every step on either chain moves work out of the model's reading and into something that runs the same way each time. Prose is a suggestion the model interprets, and a predicate is code it cannot argue with. A skill file is text the model may read, ignore or contradict. At the other end sits a tool server, which is a process in another language that answers a schema.

So name the axis once and use it twice: how much of this can the model reinterpret? On the constraint chain that reads as reach and authority. On the capability chain it reads as encapsulation. The mechanism differs and the direction is identical.

The capability chain

The four rungs below run from open to hidden. A command hides nothing, and the model sees every word of it. A tool server hides everything except a schema, because it is a separate process that may not even share a language.

the capability chain, from open to encapsulatedonly the last two boundaries are enforced
RungWho invokes it Where it runsWhat the caller sees Boundary
command a human types it in the turn, as text every word none. It is a macro
skill the model, from a description; or a human in the turn, loaded on demand every word, once loaded convention. The model can read the file
sub-agent the parent turn a separate context window a summary context. Its tool grant is declared, not inherited by accident
tool server the model, by schema a separate process the schema process. Another language, another machine, if you like

Knowledge and behavior, which is the split underneath

A capability carries two things: what the agent knows, and what the agent does. The chain moves weight from the first to the second. A command is knowledge with no behavior, and a tool server is behavior whose knowledge you never see. The middle two carry both, in different proportions, which is why they are the hard ones to place.

knows, does, hidesfull · partial · none
Rung Carries knowledge Carries behavior Hides its internals
command··
skill·
sub-agent
tool server·

The table states the boundary, and the order of events is what makes it real. Watch what crosses back to the caller in each of the three cases below. A skill returns its whole text into the same context window. A sub-agent returns a summary of work the parent never saw.

what crosses the boundary, and whenread the return arrows
sequenceDiagram
  participant P as the parent turn
  participant S as a skill
  participant A as a sub-agent
  participant T as a tool server
  P->>S: load it, because the description matched
  S-->>P: every word, into this same context window
  Note over P,S: nothing is hidden, and the context grew
  P->>A: a task, and the grant it is allowed
  Note over A: its own context window, which the parent never sees
  A-->>P: a summary
  P->>T: a call that matches the schema
  Note over T: another process, and possibly another language
  T-->>P: a result, and no implementation
both chains, side by sidesame direction, different mechanism
flowchart TD
  subgraph CON["constraints · reach and authority"]
    direction TB
    A0["prose"] --> A1["hook"] --> A2["harness"] --> A3["factory"]
  end
  subgraph CAP["capabilities · encapsulation"]
    direction TB
    B0["command"] --> B1["skill"] --> B2["sub-agent"] --> B3["tool server"]
  end
  AX["the axis · how much the model can reinterpret · falling"]
  CON --- AX
  CAP --- AX
  class A0 dim
  class A1 warn
  class A2 pass
  class A3 block
  class B0 dim
  class B1 warn
  class B2 pass
  class B3 block
  class AX dim

The object-orientation mapping, which is exact in one place

Knowledge and behavior bundled together, with the internals hidden, is the oldest idea in object orientation. The mapping is close enough to be useful, and the places it fails are worth more than the places it fits.

the capability chain, in object termsencapsulation is the axis
RungIn object termsWhy
commanda macroit expands in place. No state, nothing hidden, no interface
skilla moduleknowledge plus optional procedures, loaded when something needs it
sub-agentan objectprivate state in its own context window, a public interface of prompt in and summary out
tool serveran interface with a separate implementationyou hold the schema. The implementation lives in another process

Three things break, and each one has a known answer. Read the table below as the design work that the analogy hands you rather than as a reason to drop it. An object you cannot trust to return the same answer twice is still an object. It just needs different tools around it.

where the analogy breaks, and what closes the gapthe gap is the design work
The breakWhat it costs What closes itWhat it is not
no determinism a method that returns something different each call. One green run proves nothing an eval over a golden set, so you measure a distribution rather than a call · property tests that assert an invariant across many runs · a variance count, the same input judged N times · a schema, which pins the shape even when the content moves · a deterministic rung underneath for anything irreversible not a unit test. There is no single expected value to assert
encapsulation is a convention a skill's boundary is politeness. The model can read the file, and often should move it to a real boundary, a sub-agent for a context wall or a tool server for a process wall · withhold the read for that path · a hook that refuses reads into it · treat the file as untrusted input if anything the agent runs can write to it not private. Nothing in a prompt is private
inheritance is a security default a sub-agent inherits the parent's permission mode unless you say otherwise, so forgetting to write something widens the blast radius declare the tool grant on every sub-agent, never inherit it · assert the child's grant is a subset of the parent's · a test that runs the child under a deny-all parent and checks it still refuses · record the effective grant on the provenance row, not the declared one not a class hierarchy. There is nothing to specialize
the schema types the arguments, not the meaning a tool server can satisfy its schema and answer the wrong question after a change you never saw contract tests against the server, run on your schedule · version the tool and treat a schema change as breaking · a golden call in the eval set, so a semantic drift shows up as a score not a type system. It checks shape, never intent
no identity two invocations of the same sub-agent are indistinguishable in the record, so you cannot attribute a failure a run id on every invocation · a provenance record naming the prompt, the grant, the model and the inputs · counts per sub-agent, not per parent turn not object identity. It is bookkeeping you have to add
The rule the second chain gives you

Move a capability up its chain when you need the boundary enforced rather than respected. A skill is the right answer for knowledge the model should read and adapt. A sub-agent is the right answer when the parent's context is the problem. A tool server is the right answer when the behavior must be identical for every caller, including the ones you did not write. Each step costs an interface, and section 14 counts what that interface buys in delivery.

6 The chain

The constraint chain: six rungs, and both directions along it

A constraint climbs by crossing two boundaries. It moves from the repository to the harness to the factory. Inside each of those, it moves from a judged verdict to a coded one. That is six rungs and one path, walked in either direction.

3i · 4i a model judges 3d · 4d code settles 1 · 5 off the chain

Two words carry this section. A verdict is inferential when a model reads the work and judges it. A verdict is deterministic when code reads the work and settles it. An inferential rung can decide what no predicate can express. It costs tokens, and it can be wrong twice, by missing a violation and by inventing one.

Cross the two verdicts with the three contexts and you get the six rungs. The numbering keeps faith with the ladder on my other pages. Rung 3 is now written 3d, and rung 4 is now written 4d. Nothing you already reference has moved.

Inferential · a model judges
Deterministic · code settles
charter
rung 0 · the rule prose the model reads and applies free to write, free to ignore, and it enforces nothing
rung 2 · the hook the repository's own script, on an event cheap and mechanical, and the agent it governs can delete it
harness
rung 3i · the judging phase a phase inside the turn that reads and refuses holds rules no predicate can express. Give it no editor
rung 3d · the predicate code in front of every call the model makes exact, cheap per call, and blind to what it cannot parse
factory
rung 4i · the review stage a pass that reads the finished work sees everything the turn produced, and nothing about how
rung 4d · the stage gate a gate on the diff and on what gets published the last mechanical rung the factory controls

Two rungs sit off the chain, and both stay off it for a reason. Rung 1 is the tool grant, and it withholds a whole capability rather than deciding a case. So a rule cannot move there and stay the same rule. Rung 5 is CI. It sits outside the process that produced the work, and outside the process that checked it. Move your rules there and you spend the one rung that can tell you the others are lying.

the chain, up and downpromotion and demotion walk the same path
flowchart TD
  R0["0 · rule · prose the model reads"]
  R2["2 · hook · the repository's own file"]
  R3i["3i · harness inferential · a judging phase in the turn"]
  R3d["3d · harness deterministic · a predicate at every call"]
  R4i["4i · factory inferential · a review stage on finished work"]
  R4d["4d · factory deterministic · a gate on the diff and the publish"]
  R0 -- "recurs, and someone can name the case" --> R2
  R2 -- "other repositories need it too" --> R3i
  R3i -- "the judgment became a predicate" --> R3d
  R3d -- "the tree matters more than the call" --> R4i
  R4i -- "the reviewer keeps saying the same thing" --> R4d
  R4d -- "the gate fires on cases nobody meant" --> R4i
  R4i -- "the reviewer adds nothing the harness missed" --> R3d
  R3d -- "the predicate and the rule came apart" --> R3i
  R3i -- "only this repository ever cared" --> R2
  R2 -- "nobody can say why it exists" --> R0
  class R0 dim
  class R2 warn
  class R3i warn
  class R3d pass
  class R4i warn
  class R4d block

Why this order, and not some other

Each step does one of two things. It moves the rule further out of the agent's reach, or it makes the verdict more exact inside the same context. The second move is cheaper than the first, so take it first. Turning a judged rule into a predicate costs one function. Moving a rule from the harness to the factory costs a boundary and a new blind spot.

The reviewing phase was in my model for a long time as a capability, and I never noticed it was also a rung. That is why an older version of this page ended its promotion section with the line that undecidable rules stay prose forever. They do not. They stay undecidable, which is a different claim, and rungs 3i and 4i are where undecidable rules go.

Why the backstop is kept during a promotion

A rule carried at both an in-harness check and a stage gate is not one rule enforced twice as hard. It is one predicate at two boundaries, because an in-harness check sees tool calls and a stage gate sees the finished tree. Moving the chain rung must not silently remove the rung that catches what the moved one cannot see.

7 What a rung sees

Every rung trades reach against blindness

Choosing a rung is choosing what it can see and who can remove it. Those two properties are what the design is about. Nothing else about a rung matters much, and the blind spot matters more than the reach.

reach what it can see authority who can remove it cost what a firing spends
every rung, four properties eachread the blind spot column first
RungSees Blind toAgent can remove Cost per firing
0 · rule everything, weakly nothing, and it enforces nothing it can reinterpret it context, on every turn
1 · grant nothing. The tool is simply absent cases, entirely no nothing. It never fires
2 · hook every agent that reads the settings an agent that does not read them yes. It is a file in the repository a process, per event
3i · judging phase intent, wording, and whether a claim is supported anything outside its own context window no a model call, and it can be wrong twice
3d · predicate every call the model makes, including to tools you did not write inside a shell command it does not parse no microseconds
4i · review stage the finished work, and whether it answers the contract how the work was produced, and anything reverted no a whole extra pass
4d · stage gate the finished diff, and what is published anything mid-turn that was reverted no one pipeline step
5 · CI the merged result the whole turn no, and nor can the factory a build

The coverage grid, which is the same table read sideways

Six things exist for a rung to see, and no rung sees all six. Put your rungs in this grid and the empty column is the rule you believe you enforce and do not.

what exists to be seen, and which rung sees itan empty column is an unenforced rule
Rung Tool call Shell write Reverted work Finished diff Published text Merged result
1 · grant·····
2 · hook···
3i · judging phase·
3d · predicate····
4i · review stage····
4d · stage gate····
5 · CI·····

Rung 2 is the interesting cell, because a hook is charter content and mechanical at the same time. That mix makes it the cheapest mechanical rung to own, and the agent it governs can delete it. Every design decision about rung 2 follows from those two facts together.

Rung 3d taught me the reach lesson expensively. It used to sit inside three editing tools, so a turn writing through a shell heredoc walked straight past it. That happened twice in testing. It now sits in front of every call the model makes, including calls to tools nobody on my side wrote. That move is what makes reaching for stock tools safe.

No predicate had a bug, and tightening one would have fixed nothing. A rung watches a path, so ask of any rung whether the thing it governs has a second path. Ask before you tighten anything.

The rung 4 property nobody models

A stage gate sees two things: the finished diff, and what the pipeline is about to publish. No tool writes a commit message, a pull request body or a review comment, and none of them appear in a diff. Give your model no rung that sees published text, and every rule about what your organization says in public goes unenforced while looking enforced.

8 Across a graph

What crosses into a sub-agent, and what quietly does not

A rule that reaches your main turn does not automatically reach a child turn. Some rungs cross a context boundary and some cannot, and the split is not the one people expect. The deeper your graph, the less prose can hold it.

crosses mechanism does not prose partitions budget

Section 5 gave a sub-agent its own context window, and that isolation is the point. It is also the problem, because a fresh context window starts without your charter. So ask three questions of every child turn. Does it see the rules? Does it inherit the grant? Which rung catches it when it breaks something?

what crosses into a child turnthe first row is the one that surprises people
WhatCrossesWhy
rung 0 · the ruleno, unless you copy it inprose lives in a context window, and the child got a new one
rung 1 · the grantyes, and it can only narrowthe parent declares what the child may call, so this is the one inheritance that works
rung 2 · the hookyesthe runner fires it on an event, and it does not care which turn caused the event
rung 3i · the judging phasenojudging is a phase of one turn. A child needs its own, or none
rung 3d · the predicateyes, if it is mounted in the harnessit sits in front of every call from any turn. Mount it in the parent's prompt and it crosses nothing
rung 4i and 4dyes, oncedelivery sees the joined result, so a child's work is graded but a child is not
memory and contextno, and that is deliberateisolation is what you paid for. Passing it all through buys you a slower parent
the budgetit partitions, and it must not copyhand each of five children the job budget and you authorized five times the spend

Read the first and fifth rows together, because together they are the argument. Prose does not survive a context boundary, and a predicate mounted in the harness does. So a fleet that leans on rung 0 gets weaker with every level of fan-out. One that leans on rung 3d does not.

one parent, two children, and what reaches themthe charter stops at the boundary
flowchart TB
  H["the harness · rung 3d mounted here, in front of every call"]
  P["the parent turn · charter loaded, rung 0 present"]
  C1["child turn · a fresh context window"]
  C2["child turn · a fresh context window"]
  H --> P
  P -- "task and grant, never the charter" --> C1
  P -- "task and grant, never the charter" --> C2
  H -- "every call, from any turn" --> C1
  H -- "every call, from any turn" --> C2
  C1 --> J["the join"]
  C2 --> J
  J --> G["rung 4d · grades the joined result, not each child"]
  class H pass
  class P warn
  class C1 block
  class C2 block
  class J dim
  class G warn

Counting, when there are many children

A rule mounted once still fires many times per job, so a per-job count hides which child broke it. Record the firing against the rung and the child that caused it. Otherwise a fan-out of twenty makes one badly briefed child look like a rule that fires constantly.

The identity of the rule does not change inside a child, and neither does its layer. Only the record needs the extra field. That is a small change, and skipping it is how a healthy fleet reports a rule as noisy.

The design rule this hands you

Decide how deep your graph goes before you decide where your rules live. One turn deep, prose is fine and cheap. Two or more turns deep, anything that matters belongs at rung 1, rung 2 or rung 3d. Those are the three that cross a boundary without you copying anything.

9 One identity

What makes a constraint good: one identity, one predicate, many mounts

A rule that travels needs three things. A stable identity across repositories, a decision procedure that exists once, and an answer for when a repository disagrees. Get all three and teams share the harness. Miss one and they copy it.

id stable across repos predicate written once collision resolved out loud

A team standard restated in every repository is not a standard. It is a copy, and copies drift. So a shipped rule travels with the harness rather than with any repository, and its predicate travels beside it. Nobody shared a rule whose decision procedure has to exist in every repository it governs. They pasted it.

The same predicate then mounts at every rung that needs it. That means the repository's hook, the in-harness check, and the stage gate. Two implementations of one rule will disagree, and the agent finds the seam before you do. One function, several mounts, and a record of each firing against the rung that caught it.

When a repository disagrees

Here sits the only genuinely interesting decision in the model, and it is a domain decision rather than a technical one. A project declares a rule with the same identity as a shipped one. Who wins?

collision, resolvedeither outcome is recorded
Shipped ruleProject declares the same idResult
ordinary a local adaptation the project wins. The shipped layer is recorded on the surviving rule
locked: true a local adaptation the shipped rule holds. The attempt is recorded on it as an override attempt

The order of events matters as much as the outcome, because the harness writes the record on the way through. Both branches below end with something written down. That is the property to keep if you take nothing else from this section.

a collision, resolved and recordedboth branches write to the record
sequenceDiagram
  participant H as the harness
  participant P as the project
  participant R as the record
  H->>H: load the shipped rule
  P->>H: declare a rule with the same identity
  alt the shipped rule is ordinary
    H->>H: the project rule wins
    H->>R: write the shipped layer onto the surviving rule
  else the shipped rule is locked
    H->>H: the shipped rule holds
    H->>R: write the attempt down as an override attempt
  end
  H-->>P: the surviving rule, and its collision record

The project wins by default, because a repository knows things the harness does not. A layering nobody could adapt locally gets routed around within a week. That repeats the risk-appetite argument. Nobody obeys a control with no sanctioned deviation. They evade it quietly, and then you lose the register too.

locked marks the floor of the band, and it stays deliberately rare. It names the rules an organization has closed to a project's judgment. Either way the surviving rule carries a record of the collision, because a standard replaced in silence is worse than both outcomes.

The containment rule that comes with all of this

A predicate resolves against the tree it came from and may not leave it. A project rule cannot reach out of its repository, and a shipped rule cannot reach out of the harness package. Drop that containment and a rule file becomes a way to run arbitrary code from wherever it points. The layering you built to hold a band becomes the hole in it.

10 Honest by default

What makes a constraint good: it fails visibly and it says why

Every default in this model prefers a mistake that reads as too narrow over one that is quietly too broad. A rule that is wrong where nobody can see it does more damage than no rule. The band looks held when it is not.

why required to survive escape counted, not hidden broken reported, never blocking
defaults, and the failure each one prefersevery default has an argument
FieldUnreadable value becomesWhy that direction
layerproject a mistyped org standard governs one repository, visibly too narrow, rather than silently too broad
rung0 · prose a typo that silently became a gate is a rule nobody wrote
policyrefuse warn turns a typo into an unenforced rule, and ask parks a turn waiting for a human nobody told
verdictdeterministic a missing predicate fails loudly when the rule loads. An inferential default spends tokens on every turn and says nothing
lockedfalse a rule does not become an iron law because someone typed locked: probably

Those five apply one design decision five times. When the model cannot read what someone meant, prefer the visible failure over the quiet one. The same instinct makes a broken gate report itself and let the work through. Fail closed instead and it stops the pipeline for a reason nobody can see.

So count a broken predicate against its rule rather than only printing it. A gate that reports itself in prose nobody aggregates is how a rung rots while the table shows nothing. Counting separates a control from a control you can test.

The refusal is part of the design

What a rule says when it fires is a domain concern. People learn to route around a refusal that names no way out. A good refusal carries the rule's own words, its recorded reason, and its escape hatch. Then it says plainly that someone counts every use of that hatch.

The why field earns its place at one moment, years later. A rung whose reason nobody can reconstruct is enforcing institutional memory it does not have. Section 20 turns a missing why into a deletion signal for that reason.

Who checks the checks

Every gate here fails open on its own bug, which is the right trade and leaves one question unanswered. You cannot ask the gates whether the gates work. So at least one rung has to sit outside the process that produced the work, and outside the process that checked it.

That is the whole argument for keeping a rung in CI, or anywhere else the agent and the pipeline both cannot reach. It will be the quietest rung you own. It is also the only one that can tell you your other rungs have been reporting success into a void.

Escape hatches are the exceptions register

A recorded deviation beats an unsanctioned one nobody logged, which is the argument every risk function makes. So the hatch stays, and the harness counts its use per rule. A rising count does not argue for removing the hatch. It shows the rule and its predicate have come apart, which is a demotion signal.

11 Prose that lies

Injected text is a rule at rung 0, and the model cannot tell the difference

Rung 0 is prose the model reads and applies. Injected text is prose the model reads and applies. Those are the same operation, which is why no rule that matters for security can rest on an inferential rung alone.

injectable 0 · 3i · 4i not injectable 1 · 2 · 3d · 4d · 5 the split who reads it

A model reading its charter and a model reading a poisoned file are doing one thing: turning tokens into behavior. Nothing in the context window is labeled trustworthy. So a sentence in an issue comment, a dependency README, a retrieved document or a tool result arrives with one standing. It is the standing of a rule you wrote and reviewed.

The verdict attribute makes this precise, which is the reason it is worth having. An inferential rung decides by reading, so anything that can be read can argue with it. A deterministic rung decides by running code, and code does not get persuaded.

which rungs an attacker can talk tothe injectable column is the inferential column
RungInjectableWhat that means
0 · ruleyesprose against prose, and the newer prose is often closer to the question
1 · grantnothe tool is absent, and no sentence conjures one
2 · hooknothe runner fires it, and the model is not consulted
3i · judging phaseyesa judge that reads the work also reads whatever the work contains
3d · predicatenoit inspects the call, not the argument for the call
4i · review stageyesthe reviewer reads a diff an attacker may have written
4d · stage gatenoit runs a predicate over a tree
5 · CInooutside the process, and outside the conversation

The pattern is exact: every inferential rung is injectable, and every deterministic one is not. That is no coincidence. The thing that lets an inferential rung judge the undecidable is the same thing that lets an attacker address it.

The recursive version, which is the one to worry about

Section 5 called a skill's boundary a convention rather than a wall. Here is what that convention costs. If an agent can write to its own charter, its own skill files or its own rubric, then it can author rung 0. An attacker who reaches any of those files has not bypassed your rules. They have written new ones.

So treat the rule files, the skill files and the rubrics as code rather than as content. They get a review, they get an owner, and no turn writes them without a human merging it. That is the same containment argument as section 9, pointed at a different target.

defenses, and what each one actually buysnone of these is complete
DefenseBuysDoes not buy
a deterministic rung under every security rulea decision an attacker cannot addressanything for rules code cannot settle
withhold the capabilitya violation nobody can express, injected or notcapabilities the work genuinely needs
mark provenance on every tokenthe model can be told which text is untrusteda guarantee it will act on the marking
treat tool output and retrieved text as dataa stated rule, and a testable oneenforcement, because the rule itself sits at rung 0
humans own the rule and skill filesrung 0 stops being agent-writableprotection from what the agent reads elsewhere
a classifier on input or outputa measurable filter with a known error ratecertainty, and it is itself inferential
The sentence to take from this section

Put a deterministic rung under every rule whose violation would be a security incident. Treat the inferential rung above it as a filter rather than a control. Section 24 carries this as a numbered rule, and Prompt Injection is where I work through the attacks themselves.

Part II

The catalog

Every primitive the model names, then the patterns people build from them. The catalog is here so you can see what you are choosing against. Nobody runs all of it, and I do not.

12 Primitives

Every primitive, by family, context and reach

About fifty things, and each one belongs to exactly one family. Place a primitive in the wrong family and you will manage it with the wrong lifecycle. That is the most common modeling error, and the table below is the fix.

constraint 12 capability 10 setting 10 evidence 10 state 10

Read the reaches column as the rungs a primitive can occupy, not as a rank. A tool server and a predicate are both good designs, and they answer different questions. The watch for column carries the failure I would look for first in a review.

the primitive catalogone primitive, one family
PrimitiveWhat it is ContextReachesWatch for
Constraint · it refuses, so removing it lets the agent do more
rulea named constraint with prose, metadata and an optional predicatecharter0 to 4da rule with no identity cannot be promoted or counted
hooka repository script the runner calls on an eventcharter2the agent it governs can delete the file
predicatethe decision procedure a rung asksany2 · 3d · 4dtwo implementations of one rule will disagree
conventiona stated pattern with no predicate under itcharter0it promotes only once someone can name the case
judging phasea phase inside the turn that reads the work and refusesharness3igive it no editor, or it repairs what it should report
review stagea pass that reads the finished work and returns a verdictfactory4iit shares the author's blind spot if it shares the prompt
gatea stop between two stagesfactory4da gate that fails closed on its own bug stops the line invisibly
guarda check inside a stage that stops that stagefactory4dcount its firings, or it rots while the table shows nothing
allowlistwhich actions run without askingharness1 · 3dwidening it is a change to the band, so record it
schemathe shape an output or a call must satisfyharness3dit checks shape and never intent
classifiera model that scores an input or an outputharness · factory3i · 4iit has a false positive rate, so measure it before you trust it
containment rulea predicate resolves against its own tree and may not leave itharness3ddrop it and a rule file becomes arbitrary code execution
Capability · it enables, so removing it lets the agent do less
toola callable the model may useharnessgranted at 1withholding it is the cheapest enforcement there is
commanda named entry point a human typeschartercapability rung 1it hides nothing, so it is not a boundary
skillinstructions loaded on demand rather than at startupchartercapability rung 2the model chooses it from a description, so the description is the trigger
sub-agenta separate context window with its own prompt and grantharnesscapability rung 3declare its grant, because inheriting one widens the blast radius
phasea named step of a turn with its own prompt and grantsharnesscapability rung 3two phases that need each other's context are one phase
tool servera separate process exposing tools over a protocolharnesscapability rung 4version it, and treat a schema change as breaking
retrieval indexa corpus the model may search instead of loadingharnessa stale index produces a confident wrong answer
sandboxa bounded place a command may runharness1a sandbox holding the production credentials is not a sandbox
worktreean isolated checkout one job ownsfactoryservices outside the worktree are still shared
plan modea state in which writes are withheld until a human agreesharness1approval becomes a reflex, so keep it rare
Setting · a value moves, and no rung moves
budgettokens, money or wall clock for one jobharnessexhausting it must escalate, never truncate in silence
turn caphow many model calls before the loop stopsharnessa cap set by feel throws away correct work
revision caphow many retries after a refusalfactorymeasure the distribution before you tune the number
concurrency caphow many jobs run at oncefactoryit is your backpressure, so make it visible
modelwhich model serves this phaseharnessrecord it, or you cannot attribute a failure
thinking levelhow much reasoning budget one call getsharnessa setting, and never a constraint
samplinghow much the output is allowed to varyharnesspin it before you measure variance, or you measure the knob
policyrefuse, ask or warnanyan attribute of a rule, and also a default for rules that omit it
orderingwhich stage runs whenfactoryordering is a constraint you cannot see in any rule file
timeouthow long before a step is abandonedfactorya timeout with no owner escalates to nobody
Evidence · it measures, and it never refuses
evala scored measurement over a fixed set of casesanywherenever a rungit answers what no predicate can decide
golden setthe fixed inputs an eval runs onanywhereif the agent can edit the set, the set is not golden
rubricthe criteria a judging rung appliesanywherepublish it, or the judge is unauditable
recordthe durable row for one jobfactoryone row, one job, one identity
logthe ordered events of one runanyprose nobody aggregates is not evidence
tracethe timing and nesting of callsanythis is where cost per job actually comes from
countfirings per rung, and hatch uses per ruleanycount per rung, never only per rule
verdicta pass or a fail, with the evidence under itanya verdict with no command under it is unproven, not done
provenancewhat produced this, from what inputs, under what grantfactoryrecord the effective grant, not the declared one
cost rowtokens and money for one jobfactoryaggregate spend attributes nothing to anything
State · it persists, so it governs work it never saw
context windowwhat the model sees on this callharnesseverything in it is paid for on every turn
charterthe standing instructions for one repositorycharter0give it a fixed size, so a new rule displaces an old one
memorya fact carried between sessionsharnessgive it a layer, a scope and an expiry, or derive it instead
transcriptthe turn so farharnesscompaction is where a constraint quietly falls out
scratchpada file the agent writes to think incharterunread scratch becomes memory nobody scoped
todo listthe agent's own plan, visible and steerableharnessit drifts from the contract, so compare the two
checkpointa restorable point in the workfactorynothing checkpoints the world outside the tree
contractwhat was asked, and what done meansfactorythe system working from it may never rewrite it
amendmenta human's answer to a mid-flight questionfactoryit must travel to every later check, or reviewers grade a withdrawn requirement
artifacta produced file, diff, message or commentfactory4dpublished text is an artifact that no diff shows
The two rows people argue about

A hook looks like infrastructure and is charter content, because the repository writes it and the repository can delete it. An eval looks like a gate and is evidence, because it returns a score rather than a refusal. Get those two wrong and you will version a hook centrally, and let an eval block a merge. Those are the same mistake, pointed in opposite directions.

13 Harness patterns

Harness patterns: what happens inside one turn

The harness holds a single turn. Twenty-four patterns live here, and they trade three things against each other: tokens, reach and how much the model may decide. Every one of them has a failure mode, and the failure mode is the reason to read the row.

scope one turn currency tokens and reach rungs 0 · 1 · 2 · 3i · 3d

Start with the shape of a turn, because the patterns are all edits to it. The model plans a call, a rung decides whether that call happens, the call runs, and the loop repeats until something stops it. Every harness pattern either changes what the model sees, changes which rung decides, or changes when the loop stops.

one turn, with the rungs in placea refusal returns to the model, and does not end the turn
flowchart TB
  P["prompt · charter, contract, context"] --> M["the model plans a call"]
  M --> G1{"rung 1 · is the tool granted"}
  G1 -- "absent" --> M
  G1 -- "granted" --> G3{"rung 3d · does a predicate refuse"}
  G3 -- "refuse" --> B["the refusal · its words, its why, its hatch"]
  B --> M
  G3 -- "allow" --> T["the call runs"]
  T --> H["rung 2 · the repository hook"]
  H --> M
  M --> D["the work is done"]
  D --> J{"rung 3i · a judging phase reads it"}
  J -- "refuse" --> M
  J -- "pass" --> O["out of the harness"]
  class P dim
  class M warn
  class G1 pass
  class G3 pass
  class B block
  class T dim
  class H warn
  class D dim
  class J warn
  class O pass
24 harness patternsread the last column first
PatternWhat it does PrimitivesWhat it costsHow it fails
Shaping the loop
tool-use loopthe model calls tools until it decides it is donetool · turn captokens per stepit loops until the budget stops it, and calls that finished
plan then executewrite the plan first, then act on itphase · contractone extra callthe plan is approved and the work quietly diverges from it
plan modewithhold every write until a human agrees to the planrung 1 · plan modea human's attentionapproval becomes a reflex, so it stops being a gate
phase splitseparate prompts and separate grants per stepphase · tool grantorchestration, and lost contexttwo phases that need each other's context were one phase
budget-bounded loopstop at a token, money or clock limitbudget · turn capcorrect work discarded at the boundarythe cap is set by feel and never measured
escalate on repeat failureafter N refusals, park the job for a humanrevision cap · policy aska parked jobN is chosen by patience, not by the distribution
interrupt and steera human redirects the turn while it runspolicy ask · transcriptfull attentionthe steering is never written down, so it teaches nothing
checkpoint and rollbackrestore a known point after a bad pathcheckpoint · worktreedisk, and disciplinenothing checkpoints the world outside the tree
Shaping what the model sees
retrievalquery an index instead of loading the corpusretrieval index · contextan index to keep freshit retrieves the wrong chunk and answers with confidence
compactionsummarize the transcript so the turn fitstranscript · contextdetail you cannot get backthe summary drops a constraint and nothing notices
scratchpadthe agent writes its reasoning to a filescratchpada file to clean upit becomes memory nobody gave a layer or an expiry
todo steeringthe agent keeps a visible, editable task listtodo listvery littlethe list drifts from the contract and nobody compares them
prompt cachingkeep a stable prefix warm across callscontext · orderingordering constraints on your prompta changed prefix silently costs more and nothing reports it
sub-agent isolationa fresh context window for a sub-tasksub-agenta handoff, and a summarythe parent loses what the child learned on the way
model routinga cheap model first, escalating on failuremodel · recordtwo failure modes instead of onethe record does not say which model was wrong
Deciding what is allowed
least privilegewithhold the tool rather than write the rulerung 1a capability nobody hasthe agent reaches the same end through a shell
deterministic tool wrapperthe tool refuses, so the model never gets the chancepredicate · rung 3dwriting the predicatea second path to the same effect walks straight past it
sandboxed executionrun commands where the damage is boundedsandboxsetup, and a slower loopthe sandbox holds the credentials, so it bounds nothing
structured outputconstrain the answer to a schemaschema · rung 3drigiditythe schema fits perfectly and the content is wrong
injection defensetreat retrieved text and tool output as data, never instructionsrung 3d · classifierfalse positivesthe rule lives only in prose, where the injected text also lives
Judging the work
reviewer with no editora phase that judges and cannot repairsub-agent · rung 1 · 3ione extra passnothing downstream acts on what it found
self-critiquethe model grades its own output before returning itphase · 3itokensit agrees with itself, because it shares every assumption
chain of verificationrestate the claims, then check each one separatelyphase · predicatetokens, and latencyit verifies the wording rather than the fact
generate and testwrite the failing test first, then satisfy ittool · predicatea real test run per attemptthe agent edits the test until it passes

Four of those rows are the same idea at different prices. Least privilege, the deterministic wrapper, the reviewer with no editor and structured output all remove the ability to express a violation. That is the cheapest enforcement in the model, and section 19 gives it a name.

The judging patterns need one warning that the table cannot carry. A model grading its own work shares every assumption that produced the work. So a judging rung earns its keep when it has a different prompt, a different context, or a published rubric. Give it none of those and you have bought agreement.

The pattern I would add first

If you run one of these, run the deterministic tool wrapper. Mount it in front of every call, rather than inside the tools you wrote. No other pattern here reaches calls you did not write. That reach is what makes a stock tool safe to hand an agent. Treat the rest of the list as optional next to it.

14 Factory patterns

Factory patterns: what happens between turns and across jobs

The factory holds many turns, many agents, and everywhere work waits. Twenty-four patterns live here. They trade throughput against how much you can say afterwards about what happened. The second of those is the one teams discover they needed.

scope many jobs currency throughput and evidence rungs 4i · 4d · 5

A factory is a pipeline with a record under it. Work arrives as a contract, gets an isolated place to happen, passes through stages, and stops at gates. What separates a factory from a script is the record: every stage writes what it did, so the counts in section 20 exist.

the pipeline, with its gates and its ways outevery path out is recorded, including the parked one
flowchart TB
  I["intake · a written contract"] --> W["a worktree, one per job"]
  W --> S1["plan"]
  S1 --> S2["build"]
  S2 --> S3["test"]
  S3 --> G3{"rung 4d · the stage gate"}
  G3 -- "refuse" --> R["retry, briefed with the gate's own words"]
  R --> S2
  G3 -- "pass" --> S4["review · rung 4i"]
  S4 -- "rework" --> R
  S4 -- "pass" --> HU["the human merge gate"]
  HU -- "merge" --> CI["rung 5 · CI, outside all of it"]
  HU -- "close" --> X["recorded, and not merged"]
  R -- "revision cap reached" --> PK["parked, and visible"]
  class I dim
  class W dim
  class S1 dim
  class S2 dim
  class S3 dim
  class G3 pass
  class R warn
  class S4 warn
  class HU block
  class CI block
  class X dim
  class PK block
24 factory patternsread the last column first
PatternWhat it does PrimitivesWhat it costsHow it fails
Getting work in
intake queuejobs wait, and workers pull themrecord · concurrency capa queue to watchqueue depth hides a gate that has been refusing everything
contract as inputnothing starts without a written statement of what done meanscontractauthoring time, per jobthe contract is written by the system it is supposed to govern
worktree per jobone isolated checkout, owned by one jobworktreedisk, and setup per jobthe services outside the worktree are still shared
backpressurerefuse new work rather than degrade running workconcurrency capvisible waitingthe cap is invisible, so the queue looks like a slow factory
Moving work through
stage pipelineplan, build, test, review, ship, in that orderstage · orderinglatency per stageone stage quietly does all the work and the rest are theatre
gate between stagesa stop that the work must pass to continuegate · predicatea stopped jobit fails open on its own bug and nobody counts that
fan out and fan inparallel agents, and one join at the endconcurrency cap · sub-agentmerge conflictsthe join has no arbiter, so the last writer wins
shard by modulesplit work along boundaries the code already hasorderinguneven shardsa change that crosses shards belongs to nobody
map then reducethe same operation over many files, then one summarysub-agent · recordcost, multipliedthe summary hides the outliers, which were the point
supervisorone process owns ordering, retries and escalationordering · recorda single point of failurethe supervisor grows until it becomes a second harness
blackboardagents read and write a shared working statestate · recordcontentionthe shared state has no layer, no owner and no expiry
retry with briefthe refusal's own words become the next attempt's promptpolicy · recorda turn per attemptthe retry runs without the brief, so it repeats the failure
revision capstop after N attempts and park the jobrevision capcorrect work discardedN is tuned by patience rather than by the record
dead lettera job that cannot proceed waits somewhere visiblerecord · policy asksomeone has to looknobody looks, and the park becomes a bin
Deciding what ships
review stagea second pass reads the finished work against the contractrung 4i · rubricone whole passthe reviewer shares the author's prompt, so it shares the blind spot
merge queueintegration is serialized, so nothing merges into a moving targetorderinglatencyagents race the queue and rebase over each other
eval gatea scored set must not regress before work shipseval · golden setmaintaining the setthe set becomes the thing being optimised, so it stops measuring
canary runrun the new configuration beside the old onerecord · evaldouble the costnobody compares the two, so it is just double the cost
progressive rolloutwiden the blast radius in named stepsordering · budgetslowness, on purposethere is no defined step backwards
rollbacka defined and rehearsed way backcheckpointrehearsal nobody wants to scheduleit exists on paper and has never been run
kill switchstop the fleet without shipping anythingsettingthe discipline to keep it workingusing it requires a deploy, which is what you cannot do
Knowing what happened
provenance recordwhat produced this, from what input, under what grantprovenance · recordstorage, and plumbingit records the output and not the inputs that caused it
cost per jobtokens and money on the job's own rowcost row · traceplumbingcost stays aggregate, so nothing is attributable to anything
idempotent re-runrunning a job twice does what running it once didcheckpoint · recorddesign effortside effects outside the tree are not idempotent and never were
sampling audita fixed fraction of passed jobs is read by a humanrecord · rubrica slice of attention, foreverthe fraction drifts to zero and nobody announces it

Three of those rows exist only to make the rest measurable. The provenance record, the cost row and the sampling audit produce nothing a customer sees. They are also the difference between a factory you can tune and one you can only restart. So build them before you need them.

The sampling audit deserves the extra sentence, because it is the pattern that decays quietest. Nothing else in the list checks the gates themselves against reality. Set the fraction, name the owner, and put the number on the same dashboard as throughput.

The failure that every column above shares

Almost every failure in that table is invisible rather than loud. A gate failing open, a summary hiding outliers, an audit fraction drifting to zero, a cap tuned by patience. None of them stops the line, and all of them widen the band while the dashboard stays green. That is why counting is a first-class primitive here rather than an operational nicety.

15 The human path

The contract, and the twelve places a human gets asked

Every constraint so far governs how work happens. None of them says what the work is, or what it means for it to be done. The contract does that. The human path is what happens when an agent cannot satisfy it without a decision that is not theirs to make.

contract the input of record ask mid-turn verdict at the end

A band means nothing without a statement of what was wanted. So the contract earns first-class status: written down, kept in version control, and never rewritten by the system working from it. Acceptance criteria belong there. A rule can say how to write code, and only the contract says whether this code was the point.

That gives evidence somewhere to attach. A claim of done is worth nothing alone, so demand the criteria and the proof that something exercised each one. A verdict with no command under it is unproven rather than done. Treat those two as the same and you will report a band as held.

Where a human can sit, and what each place costs

Twelve patterns, ordered by when they happen. The first four run inside the turn and are cheap and rare. The middle four run at delivery and cost a pass each. The last four are the ones that keep the whole apparatus honest, and they are the ones that decay when nobody owns them.

12 human-in-the-loop patternscheapest at the top
PatternWhen What it costsWhat the answer becomes How it fails
Inside the turn
ask mid-turnthe agent is genuinely blockedone parked turn, minutes to hoursan amendment to the contract, and the work resumesit asks about naming, so nobody reads the questions any more
plan approvalbefore any write happensone review, per joba plan of recordthe plan is approved and the work diverges from it
approval before an irreversible actionat the action, every timeattention, every timea grant for this action onlyapproval fatigue, so the click stops meaning anything
interactive steeringa person drives the turn with the agentfull attentiontacit knowledge, in one person's headnothing is written down, so the charter learns nothing
At delivery
refusal briefa gate said noone revision, one turnthe gate's own words, verbatim, as the next promptthe human fixes it by hand instead, so the rule never improves
review verdicta person reads the finished diffa review per joba comment, or a reworkthe reviewer trusts the gate that already passed it
merge gateat the end. Nothing merges itselfthe whole job waitsmerge, close or reworkthe queue length turns it into a rubber stamp
two-person rulethe highest blast radius onlytwo people, on one decisiona recorded second signatureone person holds both credentials and clicks twice
Keeping the apparatus honest
escalation on budget exhaustionthe job ran out of tokens, money or clocka parked jobmore budget, or a killthe budget is raised without anyone asking why it ran out
timeout to a humana step stalled and nothing movedan interruption, out of hourssomeone owns the stallthe timeout escalates to a rota nobody staffed
exception registerwhenever an escape hatch is usedbookkeeping onlya count per rule, and a demotion signalhatch use is not counted, so the register does not exist
sampling auditafter the fact, on work that passeda fixed slice of attentiona calibration of every gate above itthe fraction drifts to zero without an announcement

The first row is the one worth designing carefully, because it is where a human is cheapest and rarest. An agent that guesses on a contradiction produces confident work against a requirement nobody meant. An agent that asks about naming has turned a hatch into a habit, and you will stop reading the questions.

Keep the hatch narrow by design: contradictory requirements, a missing credential, a choice that destroys data, or a direction the contract did not authorise. The agent decides preferences, naming, and anything the codebase already answers, and it reports what it decided. A resumed turn then loses the hatch, because asking the same question twice is not asking.

The sequence below is the whole pattern, and the last arrow is the one people drop. A check that sees the contract without the amendment grades correct work as wrong. Build that arrow first, because the rest of the pattern is useless without it.

a mid-turn ask, and where the answer goesthe last arrow is the one people drop
sequenceDiagram
  participant A as the agent
  participant F as the factory
  participant U as a human
  participant C as the contract
  participant V as every later check
  A->>F: blocked, and here is the contradiction
  F->>U: park the turn, and ask
  U-->>F: the answer
  F->>C: attach an amendment, and leave the contract untouched
  F-->>A: resume, and this time without the hatch
  A->>F: the finished work
  F->>V: the contract and the amendment, together
  Note over V: grade against both, or grade a withdrawn requirement
An answer amends the contract, and the amendment travels

This is the part that is easy to miss and expensive to skip. If a human answers a question mid-flight, every later check must see the contract and the answer. Otherwise a reviewer grades correct work against a requirement that was withdrawn an hour earlier. The authored contract stays untouched, and the amendment rides alongside it.

Placement follows blast radius, not annoyance

One axis decides more than any other, and almost nobody writes it down. How bad is it if this is wrong, and can you undo it? A constraint about formatting and a constraint about deleting production data are not the same kind of thing. No rung saves you if you placed them by how often they irritate you.

Irreversible actions deserve the expensive answers: withhold the capability, or ask a human. Reversible ones deserve the cheap answers: refuse and let the agent adapt, or record and look later. Sort by cost of being wrong before you sort by anything else.

The one rule I do not bend

Never put an inferential rung last in front of an irreversible action. A judging phase is a good rung, and it is not reproducible. So it cannot stand alone between an agent and a deletion you cannot undo. Put a predicate under it, or put a human at it, and section 5 lists what closes that gap.

16 Anti-patterns

Eighteen anti-patterns, and what each one is a symptom of

Every one of these looks like diligence from the outside. That is what makes them expensive. A harness with all eighteen still reports success, still passes its gates, and still cannot tell you whether you are holding the band.

modeling 6 enforcement 6 evidence 6
18 anti-patternseach one looks like diligence
Anti-patternWhat it looks like Why it failsInstead
Modeling
the copied harnessevery repository holds its own copy of the rulescopies drift, and no two repositories enforce the same thingone identity per rule, shipped with the harness
rung as strictness"important rules go higher up the ladder"authority collapses into mechanism, so nothing travelskeep layer and rung as separate fields
the nameless rulea rule is a line of prose in a long filewith no identity it cannot be promoted, demoted or countedgive every constraint a stable id
memory as policya remembered fact quietly governs later workit has no layer, no owner, no review and no expiryderive it, or give it a scope and an expiry
the growing charterevery incident adds a line, and nothing removes onethe charter gets long enough that nothing in it is reada fixed size, so a new rule displaces an old one
rules that apply themselvesa loop rewrites its own constraints on its own authorityit escapes the band it exists to holdevery promotion and demotion is a pull request
Enforcement
the second patha rule sits at the tool, and a shell command writes anywayit looks enforced, and it is notmount the predicate in front of every call
two implementationsthe same rule is written once in the hook and once in the gatethey disagree, and the agent finds the seam before you doone predicate, many mounts
the unenforceable gatea predicate that measures the wording of a claimit reports enforcement it does not havekeep the rule as prose and put an eval beside it
fail closed on your own buga broken gate stops the pipelinethe line stops for a reason nobody can seefail open, and count the breakage against the rule
reviewer with an editorthe checking phase repairs what it findsnothing is ever refused, so nothing is ever recordedwithhold the editor at rung 1
a judge as the last linea model approves an irreversible actionit is not reproducible and it can be argued pasta deterministic rung under it, or a human at it
Evidence
the uncounted hatchan escape exists and nobody totals its useyou lose the exceptions register, which was the point of the hatchcount hatch uses per rule, and read a rise as a demotion signal
aggregate countingfirings are totaled per rule, across every rungyou cannot tell which rung is doing the workcount per rung, always
idle-counting the quiet rungsthe tool grant and CI look dead in the reportyour evidence argues for deleting the two backstopsexclude both by name, and say why in the report
the self-graded evalthe judge and the author share a prompt and a contextyou measure agreement rather than correctnessa separate context, and a published rubric
the contract the system rewritesthe agent edits the acceptance criteria as it worksevery later check grades against a target that movedthe authored contract is immutable, and amendments ride alongside
cost as an aggregatespend is a number on a monthly invoicenothing is attributable, so no change can be justifiedtokens and money on each job's own row

Six of those are the same mistake wearing different clothes. The copied harness, two implementations, aggregate counting, the uncounted hatch, cost as an aggregate and the nameless rule share one missing thing. That thing is identity, and giving a constraint one stops five of the six from being possible.

The one that cost me most was the second path. Nothing looked wrong, no predicate had a bug, and the report stayed green while a turn wrote through a shell heredoc. An anti-pattern you can see in a report is not the dangerous kind.

How to use this table in a review

Do not read it as a checklist. Take the three rows whose failure you could not currently detect, and build the detection before you build the fix. A harness that cannot see an anti-pattern will grow it back after you remove it, and you will not find out for a quarter.

Part III

The discipline

What the work divides into, how a constraint moves in each direction, and who holds it. This part is about people and evidence rather than about mechanisms.

17 Sub-disciplines

Eleven sub-disciplines, sorted by scope rather than by team

Constraint engineering is one job with eleven sub-disciplines. They sort cleanly by scope, from one model call up to the whole fleet. They do not sort by team at all, which is the finding that matters and the reason section 22 argues for one role.

prompt one call harness one turn loop between turns graph many jobs

Scope is the honest sort order, because it says what a change can affect. A prompt change reaches one call. A graph change reaches every job in flight. Sorting by team instead tells you who is in the meeting, and it tells you nothing about the blast radius.

the sub-disciplines, by scopethree of them cut across every scope
flowchart TB
  A["one call · prompt"]
  B["one turn · context · tool · harness · memory"]
  C["between turns · loop"]
  D["many jobs · graph"]
  E["the fleet · governance"]
  A --> B --> C --> D --> E
  X["eval · security · cost"]
  X -- "cut across every scope above" --> A
  X --> C
  X --> E
  class A dim
  class B warn
  class C warn
  class D block
  class E block
  class X pass
the eleven sub-disciplinesnone of them belongs to one side
Sub-disciplineWhat it governs ScopeContext Sits withSections
promptwhat a single call actually says, and in what orderone callharnessdevelopment13
contextwhat the model is told, and what it costs to tell it every turnone turncharter · harnessboth5 · 13 · 20
toolthe capability surface: grants, schemas, servers, boundariesone turnharnessboth6 · 12 · 13
harnessthe mechanism that holds one turn, and the rungs inside itone turnharnessboth7 · 9 · 13
memorywhat persists between turns, and what it silently governsone turn, foreverharnessdevelopment5 · 12
loopwhat happens between turns: retries, revisions, and when to stopbetween turnsfactoryboth14 · 15
graphmany turns and many agents, and everywhere work waitsmany jobsfactoryplatform14
governancethe band, the layers, the locked floor, the exceptions registerthe fleetall threeplatform0 · 10 · 22
evalmeasuring what no rule can decide, at any scopecuts acrossanywhereboth12 · 19
securityinjection, containment, least privilege, blast radiuscuts acrossall threeboth6 · 9 · 13 · 15
costbudgets, routing, caching, and attributing spend to a jobcuts acrossharness · factoryplatform13 · 14

Four of those carry most of the design weight, and they are the four I would name if someone asked what the job is. Context is what the model is told and what it costs to tell it. Harness is the mechanism that holds a single turn. Loop is what happens between turns. Graph is many turns and many agents, and where work waits.

The other seven are real and they are narrower. Prompt sits inside context, and tool and memory sit inside the harness. Above all of those sits governance. Eval, security and cost refuse to sit anywhere, because each of them is a question you ask at every scope.

Read the sits with column and the point of section 22 arrives early. Two of eleven sit with platform, one sits with development, and eight sit with both. A split that leaves eight shared disciplines is not a split. It is a standing meeting.

Where the domain sits, and what that predicts

This is DevOps territory, spanning development and platform, and owned by neither alone. The precedent is worth taking seriously rather than as a slogan. Development and operations split because deployment was somebody else's problem, and merged because a deployment nobody owned end to end failed in the gap. A reliability band fails in exactly the same gap.

18 Mining the record

Mining the session log, and joining it to the evals

Every number this page asks for already exists, unaggregated, in the logs you are already writing. Counts say what happened and evals say whether it was good. Neither one decides a promotion alone, and the interesting cases are where they disagree.

counts what happened evals whether it was good the join what to do

A session log holds the prompts and every tool call, with its arguments and its result. It also holds every refusal, the hook output, the phase boundaries, the tokens and the timings. That is the raw material for the entire evidence family. Nobody has to instrument anything new to start, which makes this the cheapest rung of the whole apparatus.

One warning before the table. The log format belongs to your runner, so this is the least portable part of the model. The signals below are stable and the parser you write is not, and I would keep that parser small for exactly that reason.

what to extract, and what each signal decidesall of it comes from logs you already keep
SignalWhere it comes from What it decides
firings per rungevery refusal event, tagged with the rule id and the rung that caught itpromotion, demotion, and whether a backstop is doing all the work
hatch uses per rulethe escape marker, in the diff or in the call that carried ita rising count means the rule and its predicate have come apart
tool call histogramthe call stream, counted by toolwhich capabilities are never used, and can therefore be withheld at rung 1
second-path evidenceshell commands that wrote files, next to the edit tools that did notwhether a rung has a blind spot. This is how I found mine
refusal to success distancehow many turns pass between a refusal and the work continuingwhether a refusal teaches. A long distance means the message is bad, not the rule
repeat refusal ratethe same rule firing more than once inside one jobthe rule is unteachable at that rung, or the brief is not reaching the retry
varianceone case, replayed N times through a judging rung, verdicts comparedwhether an inferential rung is judging or guessing
context cost per rulecharter bytes loaded, times the turns that loaded themcontext debt, which is the rot that hides because silence looks free
cost per jobtoken counts on the trace, summed to the job's recordattribution, without which no change to the model can be justified
phase timingspan boundarieswhere the loop stalls, and which phase to split or delete
from logs to a proposalthe join is the step people skip
flowchart TB
  L["session logs · prompts, calls, refusals, hooks, tokens, spans"]
  X["a small parser · one row per event"]
  C["counts · per rung, per rule, per child, per job"]
  E["evals · a score over a fixed set"]
  J["the join · counts beside scores"]
  D["the decision matrix"]
  P["a proposal, as a pull request"]
  L --> X --> C
  E --> J
  C --> J
  J --> D --> P
  class L dim
  class X warn
  class C pass
  class E pass
  class J block
  class D block
  class P warn

The join, which is where the decision actually lives

Counts on their own are ambiguous. A rule that stopped firing might be a rule nobody needs, or a rung that went blind. Evals on their own are worse, because a score that moved tells you nothing about which rung moved it. Put them side by side and the four cases separate cleanly.

firings against eval score, and what each cell argues foronly one cell argues for demotion
The eval heldThe eval dropped
firings fell demote or delete, after you have ruled out a second path. The behavior improved, or the rung stopped seeing the rung went blind. The violations still happen and something stopped catching them. Fix the mount, never demote
firings rose the rule is too broad. It fires on cases the prose never meant, and quality did not need it. Narrow it leave the rung alone. Something upstream regressed and the rung is doing its job. Go and find the regression

The top-right cell is the expensive one, because it looks exactly like the top-left in a report that shows only counts. A team watching firings alone reads a falling number as progress and demotes the rung that was protecting them. That is the argument for the join in one sentence.

A count belongs to a version of the predicate

A predicate that changed is a different classifier, so firings recorded under the old one are not evidence about the new one. Stamp every count with the predicate version. Then reset the variance measurement whenever that version changes, because a variance number averaged across two predicates describes neither.

The rule's identity survives the rewrite, which is what section 1 asks for. Its evidence does not, and the distinction is easy to miss because both live in the same row.

Test the predicate, not only the judge

A predicate is a classifier with a false positive rate and a false negative rate, and almost nobody measures either. Give it a fixture set: cases that must fire, and cases that must not. Run it in CI beside everything else.

This is the cheaper twin of a golden set, and the page has so far prescribed golden sets only for the inferential rungs. That is backwards. A deterministic rung is the easy one to test, so test it first and spend the expensive measurement on the judge.

What I actually do, and where it falls short

I parse the logs and read the counts by hand, and nothing schedules it. So the loop in section 20 runs whenever I remember it. That is the one rule of section 24 my own factory misses. Build the parser first and the schedule second, because a parser you run monthly still beats a dashboard you never wrote.

19 Promotion

When to move it up, and the test that decides which rung

A rule earns a mechanical rung by being consequential, recurrent and settleable. The third test used to disqualify most candidates. It no longer does, because settleable splits in two, and one half of it is what rungs 3i and 4i are for.

consequential recurrent settleable

Consequential means being wrong costs something, and costs it quietly. Recurrent means it has been broken more than once, by more than one person. Settleable means something can decide it without a person, and that is where the test forks. Code can settle "no float in the money module", because it is a predicate over a syntax tree. Only a reader can settle whether someone genuinely exercised a thing rather than claiming it.

So a rule that a machine cannot decide is not stuck at prose. It goes to an inferential rung, where a model reads the work and judges it. That costs tokens, and it buys a verdict nobody can reproduce. Rules that neither code nor a reader can settle stay prose and get an eval, which measures without refusing.

where does this constraint gothe withhold branch is the one people reach for last
flowchart TB
  Q1{"is being wrong expensive, and quiet when it happens"}
  Q1 -- "no" --> P0["prose · rung 0"]
  Q1 -- "yes" --> Q2{"has more than one person broken it"}
  Q2 -- "no" --> P0
  Q2 -- "yes" --> Q3{"can the capability be withheld instead"}
  Q3 -- "yes" --> P1["withhold the tool · rung 1"]
  Q3 -- "no" --> Q4{"can code settle it"}
  Q4 -- "yes" --> Q5{"does it govern this repository only"}
  Q5 -- "yes" --> P2["the repository hook · rung 2"]
  Q5 -- "no" --> Q6{"does the check need the finished tree"}
  Q6 -- "no" --> P3d["a predicate at every call · rung 3d"]
  Q6 -- "yes" --> P4d["a stage gate · rung 4d"]
  Q4 -- "no" --> Q7{"can a model settle it during the turn"}
  Q7 -- "yes" --> P3i["a judging phase · rung 3i"]
  Q7 -- "no" --> Q8{"can a model settle it from the finished work"}
  Q8 -- "yes" --> P4i["a review stage · rung 4i"]
  Q8 -- "no" --> PE["prose, plus an eval · rung 0"]
  class P0 dim
  class P1 pass
  class P2 warn
  class P3d pass
  class P3i warn
  class P4i warn
  class P4d block
  class PE dim

What a promotion actually is

A promotion should be one field in one file, and nothing else. If moving a rule up means rewriting it, re-registering it, or touching code, promotion costs too much and nobody does it. Keep the rung next to the prose it enforces, so there is no second place to forget.

Two properties are worth stealing. First, a promotion is a proposal rather than an act: it opens a pull request and a human merges it. Second, promoting to a mechanical rung with no predicate and no rubric should produce a task instead. Writing that predicate is the actual work, and a rung without one looks enforced from the outside.

three rules, three honest destinationsthe first row is the cheapest enforcement there is
The ruleWhere it goesWhy
"a check does not repair what it finds" rung 1. Do not hand the phase an editor no predicate, because the violation cannot be expressed at all
"do not commit secrets" rung 3d and rung 4d. One predicate, two mounts 3d catches the tool call, and 4d catches whatever the shell wrote
"prove it actually ran" rung 4i, plus an eval. Never rung 4d a reader can settle it from the finished work, and a predicate would only measure wording

People reach for that first row last. Before you write a predicate, ask whether that phase could hold no such capability at all. A rule nothing can violate needs no gate, no escape hatch and no counting. That is the crossing where a capability becomes a constraint, and it is the best trade in the model.

Where evals belong in this

An eval answers what no rule can decide, and it sits at any layer. It never refuses, so it is not a rung and competes with none. Treat it as the instrument that tells you whether you are holding the band. That includes the inferential rungs, where the verdict itself needs measuring. Without it, nobody knows whether a judging phase is judging or agreeing.

20 Demotion

When to move it down, which is the direction nobody takes

A harness ratchets on its own. Every incident argues for one more gate, and nothing ever argues for fewer, because no paragraph has ever failed a build. So demotion and deletion need machinery, and promotion does not.

technical context comprehension intent variance

Anything written down can rot, including the things written down to stop rot. It goes wrong in five distinguishable ways, and naming which one you have makes a count actionable. "Never fires and is six hundred words" and "nobody knows why this exists" look alike in a table and argue for different actions.

five kinds of rot, and what each one argues fornone of these is a verdict on its own
KindWhat it looks likeArgues for
technicala predicate that throws, or a gate mounted where it cannot seea fix. Nothing about the rule is wrong
contextlong, loaded into every turn, and it never firesa deletion, or a demotion
comprehensionno recorded why, or a name that lies about what it doesa rewrite, or a deletion if the why does not survive
intentthe escape hatch doing all the work, or firing on cases the prose never meanta demotion, or a narrowing
variancean inferential rung judging the same case differently across runsa predicate, or an honest admission that the rule is not settleable

Variance is the kind the earlier version of this page could not name, because it only appears once you have inferential rungs. Measure it directly: run the same case through the judging rung several times and count the disagreements. A rung that cannot agree with itself is not enforcing a rule, and no amount of prompt work will hide that from a count.

Context debt hides for the opposite reason, which is that silence looks free. It is not. The harness loads charter content into every turn that touches what it is about. So you pay for a dead rule on all of them. It also dilutes the attention left for the rules that matter.

So a rule that never fires is a demotion if it still matters. It is a deletion if nobody can say why it is there. Those are different findings, and the difference is whether the recorded reason survives the evidence. Removal is half the work here rather than the failure case, and it is the half nobody does unprompted.

the evidence loopcut any edge and the model stops learning
flowchart LR
  A["a rung fires, or a hatch is used"] --> B["the record counts it against that rung"]
  B --> C["the analysis pass reads counts, hatch use and variance"]
  C --> D["a proposal, as a pull request"]
  D --> E["a human merges it, or does not"]
  E --> F["the rule's rung, policy or verdict changes"]
  F --> A
  class A warn
  class B pass
  class C pass
  class D block
  class E warn
  class F block

Give the charter a fixed budget

Growth is the default, because every incident adds a line and nothing removes one. So set a size for the charter and hold it. When a new rule arrives and the budget is full, something else leaves, and the argument about which one is the useful part.

A budget converts an unbounded ratchet into a trade, and it puts deletion on the agenda without anyone needing to feel bad about it. It also stops the slowest failure in this whole design, which is a charter so long that nothing in it gets read.

Counting catches per rung, not per rule

Record every firing against the rung that caught it. Then "the in-harness check never catches this any more" stays a readable fact rather than vanishing into a rule-level total. When a backstop starts doing all the work, that tells you how turns are writing code. Ask why, not which rung to tighten.

Two rungs that fire on the same case earn their keep only as two boundaries. Two rungs that differ in how hard they push are redundancy, and they destroy your ability to tell which one works. Per-rung counting makes that distinction visible.

Two rungs that must never be counted as idle

A tool grant never fires by construction: the capability is absent, so there is nothing to catch. CI fires outside anything the pipeline records. Count either as idle and your report argues for demoting the two rungs whose whole value is that they stay quiet. Exclude them by name, or your evidence will be confidently wrong.

21 What it costs

What this apparatus costs, and when not to build it

Everything on this page is overhead. It produces no feature, and no customer ever sees it. Most teams should stop at the first conformance level, and a page that argued otherwise would be selling something.

level 1 an afternoon level 2 ongoing level 3 a slice of someone, forever

The strongest objection to all of this is that it is a lot of machinery for what began as a style guide. That objection is right about levels two and three, and wrong about level one. Level one is a schema and a habit, and it costs an afternoon.

what each level costs to build and to keepthe third column is the one teams underestimate
LevelTo build To keepWorth it when
1 · modeled four fields, named families, one direction on the dependency almost nothing, because it is a schema always. No team is small enough for this not to pay
2 · enforced predicates, their mounts, containment, one rung outside the process predicate maintenance, and the false positives people will complain about more than one repository, more than a few people, or one incident already
3 · measured a log parser, records, provenance, variance runs, an eval set, a sampling audit a real slice of one person's week, forever, plus storage and eval upkeep the cost of one bad merge exceeds the cost of the apparatus

I cannot tell you where that last crossover sits, and the reason is worth stating plainly. It depends on the width of your band, and section 0 already admitted that nobody has a number for the band. So the crossover is a judgment. Anyone handing you a threshold for it is guessing with more confidence than I have.

Four situations where you should not build this

when the model does not applystated so the rest of the page stays honest
SituationWhy
a human reads every lineyour band is already as narrow as it goes, so there is nothing left to hold
one person, one repositorythe layer attribute has nothing to carry, and a shared standard has nobody to share with
exploratory or research workconstraints are for output you mean to keep, and the point here is finding out what to keep
a prototype you will throw awaythe apparatus would outlive the code, which is the wrong way round

One failure deserves naming on its own, because this page could cause it. An apparatus nobody maintains reports success into a void, which section 10 already warned about in a smaller way. A level three you cannot staff is worse than a level one you actually run, because it produces numbers that look like evidence.

The order to build it in

Four fields on your rules. Then one predicate with two mounts. Then the log parser, because it is cheap and it tells you which rule to work on next. Then the eval set, then variance, then the audit. Anyone who starts at the dashboard builds a dashboard, and anyone who starts at the schema finds out what the dashboard should have shown.

22 Two roles

Constraint engineering needs both roles, and they are becoming one

Platform decides what ships and what a project may not lower. Development knows which rules are actually wrong. Split those across two teams that meet quarterly and nobody holds the band. Section 17 already showed why: eight of the eleven sub-disciplines belong to both.

platform the floor development the ground truth devops the precedent

The DevOps precedent is the argument, and it is worth stating carefully rather than as a slogan. Development and operations were split because deployment was somebody else's problem. They merged because a deployment that nobody owned end to end failed in the gap between them. That gap was invisible from either side. A reliability band fails in the same one.

So the disciplines cut across the org chart rather than along it. Whoever knows the repository writes the context, and whoever owns the budget pays for it. The loop stays a delivery concern until a revision limit throws away correct work, and then it belongs to everyone.

what each role owns, and what it cannot see aloneboth failures are real, and both are common
RoleOwnsCannot see aloneAlone, it fails this way
platform what ships with the harness · the locked floor · the record and the counts which rules are wrong in a repository it does not work in rules nobody can override, routed around within a week
development the project layer · predicates for its own code · which refusals are noise that its local fix is a company standard three other repositories need a standard restated per repository, which is a copy that drifts

The two-way traffic is the point, and the layer attribute exists to carry it. Propose a local rule as a team rule once it keeps proving itself in one repository. Bring a shipped rule down when its escape hatch does all the work in three. Both moves are pull requests, and both need someone who sees the repository and the fleet at once.

What I would not let a system do on its own

Nothing in this model should apply itself. A proposal to change a rule becomes a task or a pull request, and it passes the same gate as any other work. A loop that rewrites its own constraints on its own authority is the one thing here that escapes the band it exists to hold.

I run the analysis pass by hand, and nothing schedules it. Call that a real gap rather than a design position, and the piece I would build next. A ratchet that someone inspects only when they remember is still a ratchet.

Where to start, this week

Take the rules you already enforce. Write four answers next to each: whose it is, what carries it, what happens when it fires, and who decides. Where you cannot answer the first without the second, you have found the reason your harness does not travel. Then pick the one rule with the busiest escape hatch and ask what it and its predicate have stopped agreeing about.

Part IV

The standard

Every term defined once, then the normative rules and what a conformance claim requires. This part is the part you can hold a design against. The rest of the page argues for it.

23 Terms

Terms and definitions

One term, one meaning, one word. Every definition below is the only definition on this page, and no term has a synonym anywhere in it. A vocabulary that drifts costs the reader a lookup on every section, and a standard that drifts is a style guide.

55 terms alphabetical normative

Take the model and rename all of it if your organization already has words for these things. What must not change is the count. Four attributes, three contexts, five families, two chains. Rename a term and the model survives, and merge two terms and it does not.

terms and definitionsrename freely, and never merge
TermDefinitionKindWhere
amendmenta human's answer to a mid-flight question, which travels beside the contract and never edits itstate15
artifactanything a job produces: a file, a diff, a commit message, a pull request body, a commentstate12
bandthe range of agent output an organization accepts without a human reading every lineconcept0
blast radiushow much damage a wrong decision does, and whether it can be undoneconcept15
budgetthe tokens, money or wall clock one job may spend before it escalatessetting12
capabilitya component whose removal lets the agent do lessfamily4
capability chaincommand, then skill, then sub-agent, then tool server, ordered by how much each hidesconcept5
charterthe bounded context of one project, and the standing instructions that state what it is aboutcontext3
checkpointa point in the work that can be restoredstate12
classifiera model that scores an input or an output rather than producing workconstraint12
commanda named entry point a human types, which expands in place and hides nothingcapability5
constrainta component whose removal lets the agent do more. The entity this model is aboutfamily2 · 4
constraint chainrungs 0, 2, 3i, 3d, 4i and 4d, ordered by reach and authorityconcept6
containmentthe rule that a predicate resolves against the tree it came from and may not leave itconstraint9
contextone of charter, harness or factory. Never the context window, which is a separate termconcept3
context windowwhat the model sees on a single call, and what is paid for on every turnstate12
contractthe written statement of what was asked and what done means, which no downstream system may rewritestate15
conventiona stated pattern with no predicate under itconstraint12
cost rowthe tokens and money attributed to one jobevidence12
demotiona move down the constraint chain, proposed by evidence and merged by a humanconcept20
deterministica verdict reached by code reading the workattribute2 · 6
escape hatchthe sanctioned way to deviate from a rule, whose every use is countedconstraint10
evala scored measurement over a fixed set, which measures and never refusesevidence19
evidencea component that measures and never refusesfamily4
factorythe bounded context of delivery: how work shipscontext3
familyone of five aggregates, each with its own lifecycle and consistency boundaryconcept4
gatea stop between two stages in the factoryconstraint12
golden setthe fixed inputs an eval runs on, which nothing under test may editevidence12
guarda check inside a stage that stops that stageconstraint12
harnessthe bounded context of development: how a single turn happenscontext3
hooka repository script the runner calls on an event, at rung 2constraint12
identitythe name of a constraint, stable across repositories and across rewrites of its predicateattribute1 · 9
inferentiala verdict reached by a model reading the work and judging itattribute2 · 6
judging phasea phase inside the turn that reads the work and refuses, at rung 3iconstraint6
layerwhose constraint it is: org, team or project. It says who may change the ruleattribute2
lockedthe invariant marker. It names a shipped rule a project may not lowerattribute9
memorya fact carried between sessions, which governs later work whether or not anyone scoped itstate4
mountone place a predicate is asked. One predicate has many mountsconcept9
phasea named step of a turn with its own prompt and its own grantscapability12
policywhat happens when a constraint fires: refuse, ask or warnattribute2
predicatethe decision procedure a rung asks. Written once, mounted many timesconstraint9
promotiona move up the constraint chain, proposed by evidence and merged by a humanconcept19
provenancethe record of what produced an artifact, from what inputs, under what effective grantevidence12
recordthe durable row for one jobevidence12
review stagea factory pass that reads the finished work and returns a verdict, at rung 4iconstraint6
rubricthe published criteria a judging rung appliesevidence12
rulea named constraint with prose, metadata and an optional predicateconstraint12
rungwhich mechanism carries a constraint. Rungs 0, 1, 2, 3i, 3d, 4i, 4d and 5attribute6 · 7
sandboxa bounded place a command may run, holding no credential it does not needcapability12
settinga component whose change moves a value and never a rungfamily4
skillinstructions loaded on demand, chosen by the model from a descriptioncapability5
stage gatea factory gate over the finished diff and over what is published, at rung 4dconstraint6
statea component that persists, and therefore governs work it never sawfamily4
sub-agenta separate context window with its own prompt and its own declared tool grantcapability5
tool servera separate process exposing tools over a protocol, of which the caller sees only a schemacapability5
turnone pass of the harness: a prompt, the calls it produces, and the work that resultsconcept13
variancethe disagreement of an inferential rung with itself across runs of the same caseevidence20
verdictwho decides a constraint: inferential or deterministic. Also, a pass or fail with its evidenceattribute2 · 6
worktreean isolated checkout one job ownscapability12
The two words this page deliberately keeps apart

Context is one of charter, harness or factory. Context window is what the model sees on a call. Almost every confused conversation I have had about this model collapsed those two. The collapse hides a real question: does this rule belong to a repository, or to the machinery that reads it?

24 Conformance

Scope, the rules, and what a conformance claim requires

A standard that only describes is a style guide. This section is the part you can hold a design against. It carries the scope, twenty-nine normative rules, three conformance levels, and the evidence each level demands. My own factory does not reach level three.

scope 29 rules 3 levels evidence

24.1 · Scope

This standard covers the conceptual design of agent constraints. It says what a constraint is and what it is made of. It also says which context holds it, which mechanism enforces it, and what evidence moves it. It applies to any system where a model produces work that a person did not read line by line.

Out of scope
Any specific framework, SDK, runner, queue or pipeline. The model is deliberately portable.
A number for the reliability band. Section 0 says why I will not invent one.
Model selection, prompt wording, and anything that changes with the next release.
Organizational structure. Section 22 argues for one role and does not draw your org chart.

24.2 · The rules

Twenty-nine rules, each traceable to the section that argues for it. Read them as the shortest form of this page. If you disagree with one, the section behind it is where the argument lives. That argument is the part I would rather you took.

  1. Give every constraint an identity that survives a rewrite of its predicate, its prose and its rung.§ 1 · 9
  2. Store layer, rung, policy and verdict as four fields. Never derive one from another.§ 2
  3. Keep the dependency one way. The factory may know the harness, and the harness must not know the factory.§ 3
  4. Place every component in exactly one family, and manage it with that family's lifecycle.§ 4
  5. Move a capability up its own chain when the boundary must be enforced rather than respected.§ 5
  6. Declare the tool grant on every sub-agent. Never inherit one, because forgetting widens the blast radius.§ 5
  7. Never let an inferential rung be the last thing in front of an irreversible action.§ 5 · 15
  8. Write the predicate once and mount it at every rung that needs it.§ 9
  9. A predicate resolves against the tree it came from and may not leave it.§ 9
  10. Keep the backstop when you promote. Two rungs are two boundaries, not two strictnesses.§ 6
  11. Default every unreadable field to the visible failure, never to the quiet one.§ 10
  12. Let the project win a collision unless the shipped rule is locked, and record either outcome.§ 9
  13. A gate fails open on its own bug, and the breakage is counted against the rule.§ 10
  14. Every constraint records a why, and loses its rung when that why no longer survives.§ 10 · 20
  15. Keep at least one rung outside the process that produced the work and the process that checked it.§ 10
  16. Record every firing against the rung that caught it, never only against the rule.§ 20
  17. Count escape-hatch use per rule, and read a rising count as a demotion signal.§ 10 · 20
  18. Measure variance at every inferential rung, by running one case several times.§ 20
  19. Exclude the tool grant and CI from idle counts, by name, and say so in the report.§ 20
  20. Give the charter a fixed size, so a new rule displaces an old one.§ 20
  21. The authored contract is immutable, and an amendment travels to every later check.§ 15
  22. Every promotion and demotion is a proposal a human merges. Nothing applies itself.§ 19 · 22
  23. Put a deterministic rung under every rule whose violation would be a security incident.§ 11
  24. Humans own the rule files, the skill files and the rubrics. No turn writes rung 0.§ 11
  25. Two or more turns deep, carry what matters at rung 1, 2 or 3d. Prose does not cross a context boundary.§ 8
  26. Partition the budget across children, and never copy it to each one.§ 8
  27. Stamp every count with the predicate version, and reset variance when that version changes.§ 18
  28. Give every predicate a fixture set: cases that must fire, and cases that must not.§ 18
  29. Read counts beside eval scores, never alone. Only one of the four cases argues for a demotion.§ 18

24.3 · Conformance levels

Three levels, and each one subsumes the one below it. Most teams reach the first in an afternoon and never reach the third. Calling both of those conformant would make the word useless.

three levels, and the evidence each one demandsa claim without the evidence column is not a claim
LevelWhat it asserts RulesEvidence a reviewer can ask for
1 · modeled the design exists and is separable from the machinery 1 to 4 a rule file showing four distinct fields · a named family for every component · a context map with one arrow direction
2 · enforced the model is carried by mechanisms, and it fails honestly 1 to 15 · 23 to 26 one predicate with more than one mount · a rung outside the harness and the factory · a broken gate that let work through and got counted · a recorded collision
3 · measured evidence moves the model, on a schedule nobody has to remember all 29 per-rung counts · hatch counts per rule · a variance number for one inferential rung · cost per job · a scheduled analysis pass that has opened a demotion proposal
Where my own factory sits, since I am asking you to measure yours

wipp does not reach level three. The rule it misses is the scheduled analysis pass, because I run that by hand and nothing reminds me. That is the gap I would close first, and it is the same gap section 22 names. A standard whose author quietly exempts himself is worth less than the paper it is printed on.

24.5 · How this standard changes

The counts are the stable part. Four attributes, three contexts, five families, two chains, and the rungs on each. Rename any term to match what your organization already says, and keep the counts. Merging two of them is what breaks the model.

This page changed once already in a way worth recording. It had three attributes and one chain, and it claimed that a rule a machine cannot decide stays prose forever. Verdict, the inferential rungs and the capability chain came from that being wrong. Assume the same will happen again, and treat a version of this that admits no error as the version to distrust.

The open question I cannot answer yet

Nobody has published a number for the band, and this standard cannot produce one. What it can produce is the instrumentation: per-rung counts, hatch counts, variance at the judging rungs, and cost per job. Run those for a quarter and you will have the first honest input to the number, from your own runs. If you get there before I do, I would like to read it.