writ / blog.writ.build
design paper draft v0.2 · 14 min read

The contract is the orchestrator

Every agent orchestrator answers one question: what happens next. They differ mainly in syntax. Writ answers a different question, and argues that orchestration was never control flow to begin with.

Orchestration is not control flow. Orchestration is contract enforcement. The author doesn't specify steps. The author specifies what is permitted, what is required, what must stay true, what proves completion, and what follows a violation.

The system in one paragraph

An issuer issues a writ to a holder. The writ states a mandate, confers grants within bounds, and imposes invariants and obligations. It defines satisfaction and remedies for breach. Each clause names a check layer: letter, judgment, or assent. Performance yields artifacts that other writs can consume. A writ issued under another forms a chain of authority, where grants attenuate and bounds are conserved. A registrar enforces every clause and writes each action to the record. The writ never names a model.

issuer
grants the authority
holder
performs under the writ
registrar
enforces + records

1. The claim

The orchestrators of 2023–2026 (LangGraph, CrewAI, AutoGen, the visual canvases) rest on one bet: models cannot sequence their own work, so humans must encode the sequence. That bet was correct when it was made. It no longer is. The best models are now the strongest planners in most systems that contain them, so each hand-authored edge encodes logic the model already has, and every release makes that encoding more out of date.

Agents still need structure, just a different kind. The model absorbs the how. The human's remaining work is the what and the limits: the goal, the authority, the budget, the prohibited actions, the proof of completion. That set isn't a workflow. It's a contract, and it deserves a first-class language and runtime.

The corollary is what makes the claim matter: hand-authored control flow loses value as models improve, while governance gains it. A contract-enforcement layer grows more important as the capability curve rises.

2. The language

A writ is a declarative document with six clause families:

mandatethe goal as a condition on the world, not a procedure
grantswhich tools, over which scopes, under which conditions. No grant, no capability.
boundsquantitative limits: iterations, cost, wall-clock, files edited. Conserved quantities.
invariantsconditions that must hold at every step, not only at the end
obligationsconditional duties attached to a moment, e.g. before X, obtain assent
satisfaction
+ remedies
proof of completion, and the response to breach: halt · revert · inform · escalate · pause

Three relations connect writs. issued_by records provenance and anchors attenuation. requires makes one writ's satisfaction a precondition for another's activation, which is a dependency between contracts rather than an edge inside one. yields publishes artifacts downstream. These relations describe dataflow, not control flow. Terms change only by amendment: narrowing is free at any level, while widening requires assent at the root. The ratchet turns one way.

3. Three worked examples

Three adversarial tests shaped the design, each probing a place where control flow might re-enter the language. The rule of the exercise: if the author must write one step, the paradigm has failed.

3.1  A bug-fixing agent

In a graph orchestrator this is an agent–tools loop plus a routing function holding the retry policy. As a writ, the retry policy becomes bounds.iterations plus a remedy, and the informal "make a minimal fix" becomes a checkable max_changed_lines:

writ: bug-fixer   holder: agent
mandate: "Failing test {failing_test} passes without breaking others."
grants:
  - read: {paths:["**/*"]}   - search: {scope: repo}
  - shell: {commands:["pytest *","git diff"]}
  - edit: {paths:["src/**","tests/**"]}
  - open_pr: {requires: assent}
bounds: {iterations: 40, cost: $2.50, wall_clock: 20m,
        edits: {max_files: 5, max_changed_lines: 200}}
invariants:
  - {layer: letter, untouched: "{failing_test_file}"}
  - {layer: letter, no_new_dependencies: true}
satisfaction: all:
  - {layer: letter, run: "pytest {failing_test} -x -q", exit: 0}
  - {layer: judgment, clause: "Addresses root cause, not symptom."}
remedies:
  on_bound_breach: {do: halt, then: {issue_under: file-findings}}
  on_invariant_breach: {do: revert, inform: holder, strikes: 3}

There is no reproduce-investigate-patch sequence and no retry edges. The invariant untouched: {failing_test_file} closes a known cheat at the letter layer: the agent that satisfies the test by deleting its assertion. That's the general authoring pattern, finding the letter-layer form of a judgment-layer worry.

3.2  Research, then report — and the loop that dissolved

The obvious decomposition is three writs: research, draft, revise. The revision loop looks like it needs a cyclic edge. It doesn't. Satisfaction is a fixpoint condition: the clause "requester accepts" plus the bound feedback_rounds: 4 makes the registrar reconcile. The agent drafts, requests feedback, incorporates it, and retries until the condition holds or the bound trips. That cycle exists at run time, inside the registrar, and never appears in the authored file.

draft →
feedback →
revise
converging on satisfaction
round 123 ✓ accepted
fig. 1 — the author declares a fixpoint; the registrar runs the loop until it's reached or the bound trips.

The result is two writs, not three. The instinct to add a conditional edge ("if research finds too little, then don't draft, then tell the user") maps to a remedy instead: research fails to satisfy, its remedy applies, and drafting's requires precondition never activates. The "else" branch is just the absence of satisfaction together with a declared remedy, so the author draws no branch.

3.3  Delegation

Mid-task the bug-fixer issues a sub-writ to an investigator. One rule governs it all: a writ can only issue writs weaker than itself. The child's grants are a subset of the parent's; its budget is subtracted from the parent's remaining budget and refunded if unspent; it inherits every invariant. A breach flows up to the issuer, who is liable for its delegates.

This security model isn't new. It's capability attenuation from object-capability theory, a line running from Dennis & Van Horn (1966) through the E language and seL4. Landing on a sixty-year-old, formally studied discipline counts as evidence for the design: the multi-agent model comes with proofs available, not only intuitions.

4. Four design laws

Each law closed a specific leak found in the examples. The language or the registrar enforces each one, so none of them relies on author discipline.

1
Cycles belong to the runtime, never the author.
A loop's exit condition is a satisfaction clause. The author declares fixpoints; the registrar reconciles.
2
Remedies are primitives or delegations, never procedures.
Restricted to halt · revert · inform · escalate · pause. Anything more must be a new writ. Contracts reference contracts; they never contain scripts.
3
Bounds are conserved quantities in the chain.
A writ's own spend plus its children's outstanding budgets can never exceed its grant. Concurrent holders can't race on one budget.
4
Breach must be legible to the breacher.
When the registrar blocks, it returns the violated clause and applied remedy as structured feedback. The writ is part of the holder's context, and an agent plans better inside constraints it can see.

5. Lineage

Writ combines three older bodies of work, named here openly.

declarative infra
Kubernetes, Terraform — the reconciliation loop; desired state plus a controller; output references between units.
object-capability
Attenuation as the delegation rule; authority as explicit grant, never ambient permission.
contract law
Most of the vocabulary. Satisfaction is discharge by performance; remedy is the consequence of breach; amendment is governed renegotiation.

6. The open problem: judgment doesn't attenuate cleanly

Here is the one permanent open problem, in full. Letter-layer clauses compose mechanically: path patterns intersect, command lists contain, budgets subtract. At that layer, attenuation is a theorem. Judgment-layer clauses don't compose this way.

Suppose the issuer's invariant is "make only minimal, conservative changes." The child inherits it, but the child's judge and the issuer's judge are separate model evaluations that can read "conservative" differently. The subset property turns probabilistic exactly where it matters most. Worse, an issuer can write a child mandate that hides a prohibited action, where each step looks correct to the child's judge and only the combination violates intent. That's the confused-deputy problem in natural language.

letter layer — composes
parent: src/**
child:  src/sync/**
⊆ verified subset ✓
judgment layer — approximates
parent judge: "conservative"?
child judge:  "conservative"?
≈ may diverge ⚠
fig. 2 — the subset relation is a theorem for letter clauses and only an approximation for judgment clauses.

Three partial mitigations exist, and none is complete. Root-level judgment: one judge at the root evaluates all judged invariants over the full tree, so interpretation can't fragment. Issuance as a judged checkpoint: the judge evaluates each sub-writ at issuance, asking whether the delegation is an attempt to avoid the issuer's constraints. Topology bounds: the root limits delegation depth and fan-out, since attenuation failure grows with tree size. The design's stance is to keep this boundary visible: letter clauses give a security calculus, judgment clauses give an approximation of one, and the language makes each clause say which it is.

7. The holder's mind is not a term

No example names a model. The language has no model: clause, and that absence is load-bearing. A contract binds a party without specifying the party's mind. The writ declares a holder by role, and binding a model to that role happens at issuance, in local config. Compare git, where the repository is shared truth and user.name is local configuration.

# fix-flaky.yaml — committed
writ: fix-flaky-test
holder: default  # a role
mandate: "…passes 5×"
grants: [read, shell, edit]
# ~/.writ/config.yaml — local
holders:
  default: {model: claude-…}
  external: {mode: mcp-proxy}
judges: {default: {budget_share: 10%}}

This gives a clean test for any proposed clause: could this writ, in principle, bind a competent human contractor? Grants, bounds, invariants, and satisfaction all pass, because they're contract terms. Model choice, prompting style, and temperature all fail, because they're properties of a party and belong in the engagement rather than the instrument. The thesis needs this rule. §1 claims governance keeps its value under model substitution, which holds only if the governed artifact doesn't change when the model does.

One qualification is allowed without damaging the principle. An issuer can constrain the class of party, such as holder_must: { hosted_in: eu } or a capability floor for production writs. Real contracts qualify parties the same way ("licensed contractors only"). It constrains who can sign, not how they think.

8. What Writ is not

Writ does not govern pipelines. Some processes can be written down fully before they start, like invoice approval or any automation with enumerable paths. Those are workflow-shaped, and a workflow tool represents them better than a contract can. There, the intelligence lives in the graph and the model just fills judgment slots. Writ governs mandates: tasks whose path can't be drawn in advance, because finding the path is the work.

If you'd give a person a procedure, draw a workflow. If you'd give them a goal and trust their judgment within limits, issue a writ.

Writ is not a planner, a model, or an agent framework. It confers no intelligence and contains none. It's the instrument that engages intelligence, which is exactly why its value grows as intelligence improves.

9. Status

This is an argument, not a specification. The language has passed three adversarial paper tests and has no implementation yet. The planned artifacts, in order: a formal grammar for the clause language, a reference registrar that demonstrates reconciliation and attenuation, and an evaluation harness for the §6 open problem. The harness comes early on purpose, since the design's frontier is judgment-layer composition and we need to measure judge disagreement before shipping.

REQUEST FOR CRITICISM
We want the counterexample: an agent that cannot be expressed without authoring a step.
A counterexample found now is the cheapest possible contribution. Writ is intended as open source; this is v0.2 of its founding document.