Home / Projects / Orchestrata Ultimate / Decisions / ADR index / ADR-0033
ADR-0033: No agent merges its own work; dispatch gates on duplication and staleness
| field | value |
|---|---|
| Status | Accepted |
| Date | 2026-07-24 |
| Register | factory (docs/adr, 4-digit ids) |
| Source | docs/adr/0033-no-agent-merges-its-own-work.md — permalink at bdafa201a (unchanged on master since that commit) |
| Wiki register entry | ADR-0033 (wiki status: Accepted) |
The record
- Status: Accepted
- Date: 2026-07-24
- Spec: SPEC-033 §1, §2, §7
- Relates to: ADR-0018, ADR-0021, ADR-0022, ADR-0024
Context
The register already asserts author/judge separation in three specific places — ADR-0022 (the interpretation mutator may not adjudicate its own readings), ADR-0024 (the assumption enumerator may not adjudicate its own enumeration), ADR-0008 (structure, not self-reported intent). It is asserted per mechanism, and nowhere as a property of the pipeline itself.
That leaves the largest instance unaddressed: merge. Merge is promotion — ADR-0021 treats it as the moment a change becomes trunk reality. If the agent that authored a change can also merge it, every upstream separation is decorative, because the author holds the only irreversible privilege in the system. The autonomous-agent products that shipped this pattern converged on the same constraint independently: an agent may propose, and a distinct identity must promote.
Two adjacent dispatch-time failures share a root and are cheap to fix at the same point:
- Duplication. Nothing at dispatch checks whether the work being handed out is already in flight, or already done. Under fan-out, N agents can be dispatched onto the same requirement and each will produce a plausible, conflicting change. The system then adjudicates a conflict it manufactured.
- Staleness. A task dispatched against commit C and completed after trunk has moved is validated
against facts (ADR-0004's
(worktree, commit)keying) that no longer describe trunk. The gate reads green on a state that no longer exists.
Both are pre-dispatch conditions, and both are silent when they fire.
Decision
1. No agent merges its own work. Merge requires an identity distinct from the authoring identity — enforced structurally by the three-UID execution model (ADR-0018), not by convention or by asking. This is stated once, as a pipeline property, superseding the need to restate separation at each new mechanism.
2. Dispatch gates on duplication. Before a task is handed to an agent, the dispatcher checks whether the same requirement/change is already in flight or already promoted. A duplicate is refused at dispatch, not adjudicated at merge.
3. Dispatch gates on staleness. A task carries the commit it was dispatched against. If trunk has moved in a way that touches the task's impact set, the task is re-based or re-dispatched, never validated against the stale fact set. "Trunk moved but not in our impact set" is the fast path and stays cheap.
4. All three failures are loud. A refused dispatch and a stale re-dispatch are recorded events, not silent no-ops — otherwise duplication and staleness look identical to "nothing happened".
Alternatives rejected
- Rely on quorum instead of identity separation — quorum is a judgement mechanism; merge is a privilege. An author who can merge does not need to convince the quorum, only to outlast it.
- Restate separation per mechanism as we go (status quo) — it is how merge was missed. A pipeline-level property cannot be maintained by remembering to add it to each new component.
- Detect duplicates at merge instead of dispatch — the work is already done and paid for by then, and the conflict is now real rather than avoided.
- Always re-base on any trunk movement — correct but expensive; scoping to the impact set is what ADR-0021's coupling accounting is for.
Consequences
- Requires at least two distinct execution identities to be live for any change to complete, which makes ADR-0018's three-UID model load-bearing rather than defence-in-depth.
- A single-agent factory cannot merge. That is the intent, and it means bootstrapping and any degraded single-identity mode must route merge to the human.
- The duplication check needs a notion of task identity stable enough to compare — most likely the requirement plus the impact set, which means it depends on B4's impact query.
- The staleness check makes ADR-0019's causal-consistency requirement visible at dispatch as well as at the gate, since the dispatcher must read a trunk state at least as fresh as the last promotion.
Provenance
2026-07-24 prior-art research: the no-self-merge constraint as converged on by shipped autonomous coding agents, and the dispatch-time duplicate/staleness gate as a documented failure class. Merge was identified as the unguarded instance of a separation the register already asserts three times elsewhere.
Related ADRs
Rulings cited
None.