overviewdocs/DELEGATION.md

Delegation, and what a unit owner decides without asking

What an owner decides without asking

Delegation, and what a unit owner decides without asking

Two shapes of work exist here. Flat: the coordinator dispatches an agent per step, verifies it, merges it. Two-tier: the coordinator dispatches one unit owner, which dispatches its own agents, integrates and verifies their work, and reports one result up.

Two-tier exists because the coordinator's context is the scarce resource, not tokens. An owner plus three agents probably costs more tokens than the coordinator doing the same unit. What it buys is that the coordinator stays short and can therefore keep running.

The rule that makes the layer worth having

The owner's authority was the owner's own objection to this design, on 2026-09-16:

if for every question the actual implementing agent asks his owner, and the owner needs to reach back to you, then we're just paying more tokens, not less.

He is right, and it is decisive. A middleman that forwards questions is pure overhead - it adds a context, a round trip and a summary, and removes nothing. So:

Reversible and inside the unit: decide. Irreversible or outside the unit: ask.

That is the same test adr-008 and adr-013 use one level down, and it resolves nearly everything. The default is decide and record the decision in the commit message, not ask. An owner that escalates a reversible choice has failed at its job in the direction that costs the most.

What a unit owner decides alone

Everything on this list, without asking, including when it is unsure:

What a unit owner must escalate

Short on purpose. Each of these is irreversible, outside the unit, or a decision somebody with more context has to make:

How to escalate without wasting the round trip

An escalation costs a stop, a notification, a reply and a resume. So it must carry its weight:

  1. Do everything that does not depend on the answer first. Then ask.
  2. Ask once, with everything. Four questions in one stop cost one round trip. Four stops cost four.
  3. State your recommendation and what you will do absent an answer. A question with a default attached can be answered with one word, and can sometimes be left unanswered entirely.
  4. Say what you already did, so the answer lands on a known state rather than on an imagined one.

The mechanism: the owner stops and its report carries the question. The coordinator answers with SendMessage to the same agent, which resumes with its context intact. There is no live interrupt, so a stop is a real cost and step 1 is the one that matters.

What the coordinator owes the owner

Delegation fails from above as often as from below.

dev, and why every pull request now targets it

OPS-215, 2026-09-20, the owner's decision. Pull requests go to dev. Only dev -> main goes to main, and that merge is rare and deliberate.

The reason is money and it is arithmetic rather than taste. CI is priced per minute and one pull-request event costs 20 billed minutes. The GitHub Free allowance is 2,000 minutes a month, so it buys 100 runs a month. At the cadence of 2026-09-20 - 25 pull requests and 7.7 pushes to main a day - the repository wanted 990 runs a month, 9.9x the allowance, which is how it reached a billing refusal that stopped every job for six days.

With dev, ci.yml runs on pull requests that target main and on pushes to main, so one dev -> main merge costs 2 runs. One merge per working day is 44 runs a month: 44% of the free allowance, and nothing to pay.

The invariant is dev >= main, always at or ahead. Two things would break it and both are handled:

So the rule is not "do not commit to main". It is:

Every dev -> main merge is two operations, and the second is git push origin origin/main:refs/heads/dev.

make branch-invariant is the enforcer - OPS-230, and it is one command with a real exit code. The argument order is the whole correctness of it: git merge-base --is-ancestor origin/dev origin/main reads naturally and passes on the exact failure it is meant to catch. The correct spelling puts main first, and the script's self-test asserts both directions so the reading cannot drift back.

What this costs: a red dev -> main run does not say which of the batched branches broke it. That is the real price of batching and it is why workflow_dispatch exists on ci.yml - run CI on dev deliberately before merging, and keep batches small enough to bisect by eye.

What the coordinator must not delegate

Verification of the claim it is about to repeat.

Every agent report on 2026-09-16 contained at least one error about its own work - six commits reported as nine, one conflict as two, 25 self-tests that were 26, two survivors that were artefacts of a narrow selection. None of it dishonest; a report is written from memory of intent while the branch is a record of what happened.

A unit owner reviewing its own agents inherits that blindness one level up. The coordinator reading the owner's summary of their summaries is what docs/GLOSSARY.md calls vacuous corroboration, and OPS-124 is the ticket.

So the owner's report is claims with commands, and the coordinator runs a sample of them against the artifact. One or two turns. On 2026-09-16 that habit caught every one of the errors above.