5.3 How Delegation Changed
This chapter illustrates
✓ The Modeling Principle · ✓ The Alignment Principle · ✓ The Governed Engineering Environment · ✓ Residual Human Judgment
As the engineered environment matured, the division of engineering labor changed with it.
A finished architecture can make its structures look inevitable. Their histories show which were designed cleanly, which were forced by failure, which required later hardening, and what each allowed the engineer to stop doing by hand.
5.3.1 The Product Path
A user uploads a file. The front door authenticates the request, meters quota, and queues the job; a dispatcher divides the document into chunks; the remediation core applies deterministic rules or bounded model calls through structured document representations; the check engine evaluates remaining findings against accessibility standards; a fidelity validator looks for content lost while accessibility improved; and provenance records what changed. The corrected artifact returns with the evidence those mechanisms produced. Figure 5.3-1 gives the path.
That is the product path. The larger engineered environment around it — the subject of the previous chapter — contains the models, tests, lints, orchestration, and other machinery that made this degree of delegation possible.
The architecture narrows probabilistic work into a small action surface. Typed document models own mutation; the lower-level format libraries sit behind those models; deterministic machinery owns workflow and the mechanically decidable checks; fidelity validation covers properties visible only after a transformation has run.
5.3.2 The Model as a Bounded Subroutine
MAGE applies at two scales in this case. Coding agents act on the engineering system; frontier models also run inside the product. The second case is smaller and easier to bound: treat the model as a probabilistic subroutine inside a deterministic workflow. Deterministic code decides when interpretation is needed, packages a bounded input, requires a typed output, and evaluates the candidate against obligations the environment can decide mechanically.
The model's answer is therefore a candidate, not a verdict. A schema can reject malformed output; a standards rule can reject a mechanically invalid claim; a fidelity check can catch some classes of destructive transformation. None of those proves that an alt-text description perfectly captures the meaning of a figure. The trust boundary is only as strong as the obligations the validator can actually evaluate. Properties the checks cannot decide remain probabilistic or require human judgment. Figure 5.3-2 draws the caller, the typed contract, and the validator.
The architecture resembles proof checking in one limited respect: a powerful producer is separated from the smaller mechanism that decides whether its evidence is sufficient for admission 11. Talia Ringer et al., “QED at Large: A Survey of Engineering of Formally Verified Software,” Foundations and Trends in Programming Languages 5, nos. 2–3 (2019): 102–281, https://arxiv.org/abs/2003.06458..
The coding agents that built DocAble pose the same trust-boundary problem at a larger grain. There the engineered environment needs richer system representations, authority across several boundaries, independent evidence, and governance conversion. The bounded subroutine applies the same engineering stance inside the product that MAGE applies to the process that builds it.
5.3.3 Two Paths to Durable Structure
Not every consequential structure was born from failure. The backend became reactive and stateless early: work moved through queues, workers carried no durable truth, and a fan-in step assembled the result. That choice later made the migration from a cluster that billed around the clock to a serverless carrier much cheaper than it might have been; the business logic largely survived while the deployment carrier changed. Likewise, the document editor routed both human gestures and automated remediation through one closed edit vocabulary over the same document representation. That seam later supported a second producer without creating a second mutation path. These were dividends of prior structure, not evidence that every useful abstraction must first be purchased by an incident.
Other seams were different. Their histories begin with a concrete failure and let us trace the response in layers. Those histories expose something the finished boundaries do not: the sequence that produced them.
The computations stabilized before their composition
I made one useful decision about DocAble early, and came to a second only much later. The remediation core was organized as passes: identifiable units of computation, each responsible for some part of analyzing or changing a document. That decomposition proved durable. When we later built a static computation graph, the pass registry handed us the nodes almost for free. I had started from the computation side, and that is precisely why node projection was possible at all.
What I had not modeled nearly as well was their composition. I had not required every pass to declare, in one common vocabulary, what information it produced, what it consumed to make its output, what it read only to decide whether it should run, and how bounded its mutations were. Those facts lived in the code, not in one explicit engineering model.
I do not think the lesson is that I should have specified all of this on day one. Early in the system's development we were still learning what a remediation pass even was: which responsibilities belonged together, and which variations mattered. Some freedom was useful precisely because we did not yet know what deserved to be fixed as structure. A premature composition model might just as easily have encoded the wrong abstractions.
Composition eventually became consequential
The balance changed as the pipeline grew. A pass makes a convenient local boundary, but a loose composition contract admits many locally reasonable implementations: walk the document again, recover state another pass already computed, read a shared structure directly, mutate in place, or add one more special case. Across many passes, those choices began to interact. In one region, work whose local complexity looked harmless accumulated into O(N²)-like behavior across an O(N)-pass pipeline, because passes kept rediscovering or retraversing state; elsewhere, passes mutated the document through different mechanisms. The freedom that had supported exploration was becoming expensive to reason about.
The gap was never a total absence of structure around mutation. By this point the PDF path already captured a typed vocabulary of per-session document edits: roughly thirty edit variants, recorded in order and replayable deterministically. I had modeled meaningful computations, and we could record meaningful mutations. What stayed under-modeled was the relationship between the two — how those computations composed, and which of their effects crossed the boundaries between them.
The model exposed the distinctions that mattered
By then the way the passes composed had become too complicated to understand comfortably from the implementation alone, and the computation graph gave us a way to reduce it. Its first version contained 113 nodes and two edges. The nodes reflected a decomposition that had stabilized; the two hand-authored edges plainly did not capture the relationships among them. So we began deriving the missing composition from the passes themselves, and the first sweep found thirty-three candidate producer–consumer edges.
Trying to derive those relations raised a sharper question: consumer in what sense? Roughly two-thirds of those relationships were not data flow at all. A pass read a signal or a verdict only inside routing logic, to decide whether it should run. Treating those as ordinary data edges would have buried the real data graph in control noise. So the passes acquired a distinction they had not expressed uniformly: they now declare Produces, Consumes, and ConsumesForControl, and the graph projects two relations from them, DATA_FLOW and CONTROL_GATE. The data graph shrank to ten data-flow edges plus one cross-service payload edge; twenty-two control dependencies stayed visible, but separately.
The same exercise exposed a second hidden choice. A pass could produce a bounded typed patch, edit document state directly, or make no change at all. We classified all 68 pass sites on that axis: 15 typed-patch producers, 40 direct editors, 13 read-only. The count did not say the 40 direct editors were wrong. It showed where degrees of freedom remained.
This changed how I read the earlier freedom. Some of it had been productive exploration; we could not have known every useful distinction before building the system. But by the time composition was producing recurring global cost, leaving those relationships implicit no longer bought the same flexibility. And building the model helped show which structure should replace some of that freedom. We had not begun with DATA_FLOW, CONTROL_GATE, and the mutation kinds as a finished ontology. We found those distinctions by trying to represent the system well enough to reason about it.
Figure 5.3-3 reads top to bottom as a partial model growing the half it had been missing.
The final move was to stop maintaining those relationships as another hand-written truth. The pass declarations now carry the typed IO, the graph projects its edges from them, and a blocking parity check fails if the declarations and the projected graph disagree.
Freedom can be exploratory
The episode changed how I think about degrees of freedom. Leaving a choice open is often economically sensible: if several realizations satisfy every known obligation, pinning one of them spends effort and can make later change harder. But freedom can also be exploratory. Early in a design the engineer may not yet know which choices are consequential enough to constrain, and variation is what supplies the evidence.
The engineering question is when that freedom has done its job. One signal is recurring consequential variation: independent choices start producing global cost, failures, coordination burden, or behavior no one can follow locally. Another is complexity itself. Even before the right obligations are clear, a region can grow too tangled to explore without a representation. There, modeling precedes specification: build enough structure to reason about the territory, use the model to find the distinctions that matter, and give authority only to the obligations the exploration has revealed.
That describes what happened here better than saying we should simply have modeled more, sooner. The remediation computations stabilized before their composition semantics did. Once that composition became both consequential and hard to reason about, the computation graph helped us find which relationships deserved names and which implementation choices could stay free.
The work is unfinished, and the residuals are part of the lesson. Forty passes remain direct editors. Office-format edges are not yet projected the way PDF edges are, so that check stays audit-only. The graph is static: runtime invocation, duration, retries, cost, and model fingerprints require runtime representations beyond the computation graph. We already record typed per-session edits and can replay them deterministically, but we do not yet join that realized history to the graph's computation identities — an edit names a PDF structure element, not a computation node.
The first place those two representations deliberately touch is testing. The typed IO says where a per-node test begins, and deterministic replay removes model variance from the realized side. We could compose them for that question only because we had kept them orthogonal until a question needed them joined, rather than fusing them early.
Those residuals matter. The point of modeling was never to drive every degree of freedom to zero. It was to know where the freedom is.
The format seam. An early path used a convenient scripting-language library to slice a document. The operation worked visually and silently destroyed the internal tag structure carrying the accessibility the product existed to add. The failure exposed two missing things: an architectural decision — one canonical implementation should own mutation of that format — and environmental authority capable of keeping other paths from bypassing it.
The response came in layers, and Figure 5.3-4 draws the climb. A policy named the canonical library. A typed format model and API concentrated mutation through one seam. A build-time check refused raw access from elsewhere. Then the check itself failed: a stale repository root caused real findings to be reported as green. That second-order incident forced the gate to be hardened too. The finished structural model describes the seam; the incident history explains how it acquired that shape. The model stated the boundary; the API and check gave selected obligations over that boundary authority. The authority itself still had to be maintained.
The service seam. Another failure sent a local file path across a service boundary, where it became meaningless in the callee's process. The replacement client accepted file content but not a local path, and an explicit service graph represented which services could call which. A later human review found a second problem: an optional direct-client path could bypass shared rate limiting, key rotation, failover, and cost tracking entirely. A protection boundary only governs the paths that cross it.
5.3.4 The Delegation Staircase
The five rungs are retrospective names for the changing center of gravity of my work—co-coder, QA, review lead, tech lead, architect—not a prescribed career ladder. What matters is what the engineered environment could carry at each stage.
The staircase has two interacting supports. Alignment moved repeatable authority out of direct human review: deterministic checks, permissions, boundaries, and gates could carry obligations I no longer inspected line by line. Modeling moved system knowledge out of my head: named zones and later explicit models let agents reason over larger engineering questions without reconstructing the whole repository each time. Human judgment moved toward the gaps the environment could not yet represent or decide.
Delegation therefore climbed as far as the engineered environment could carry it. When representation was too weak, I fell back into reconstructing the map. When authority was too weak or unreliable, I fell back into reading diffs and verifying outcomes manually. A miss could send the staircase backward.
Co-coder — direct human inspection carried everything. The first system was small enough that I read the agent's changes, judged them, and merged them. The human supplied both the system context and the admission decision. That worked while the volume stayed inside one person's attention. It failed as an operating model once generation outran review.
QA — evaluation was delegated before authority was. I began dispatching a second agent to audit another agent's work. That removed some reading from my hands but did not make the result authoritative: the audit ran episodically, produced probabilistic findings, and still depended on someone to decide what followed. Its value was diagnostic. Repeated decidable findings revealed questions that no longer needed a language model at all.
Review lead — reviewers specialized by concern, while decidable findings dropped into machinery. One generalist audit over a growing codebase produced too much undifferentiated advice, so review split by concern and by region. Architecture, security, duplication, and naming could be judged in the context where they mattered. When a finding turned out to be mechanically decidable, it became a deterministic check; the probabilistic reviewers retained the questions those checks could not settle.
Tech lead — representation made reasoning local. Specialized reviewers were still finite reasoners confronting an expanding repository. Named zones externalized ownership and architectural boundaries so an agent could reason inside one region without first recovering the whole system. Boundary checks constrained some cross-zone edits. This stage combined the two principles explicitly: the zone model reduced reconstruction; selected rules over that model received authority.
Architect — explicit models carried system-level knowledge. By the final rung I rarely read implementation directly. Architectural, behavioral, ownership, and other models supplied the system views I needed for planning and review; agents used the same representations to localize changes. This did not make the models true by declaration. Model drift became its own failure class, which is why traceability and correspondence checks eventually became part of the environment. When the cost of restructuring collapses, the economics invert — a cross-format migration that touched fifty-eight files and rewrote five thousand lines took about five hours of agent time over a dinner break, and postponing the right shape becomes the expensive choice. The hard part was never touching fifty-eight files; it was knowing that fifty-eight files should be touched.
What explicit models made checkable
Explicit models changed what could be established mechanically. A lifecycle model made illegal transitions checkable. An ownership model reduced a concurrency protocol to the states and interleavings needed to ask whether two workers could hold the same claim or whether a stale holder could clear a newer lease. A small, purpose-built Python model checker exhaustively explored the finite abstract state space and checked the ownership invariants. Selected conformance tests separately exercised the corresponding production operations against the model's predictions.
Other properties called for different machinery. Eventual termination is a property over executions rather than merely reachable bad states, so I wrote small TLA+ specifications and checked them with TLC. The specifications modeled failure and recovery explicitly: when recovery was disabled, TLC produced the stranded execution the property was intended to exclude.
Checking the model created a second obligation: why should a property established over the model be believed about the implementation? DocAble never answered that question with formal refinement or implementation-level model checking. For the ownership protocol, selected conformance tests exercised real production operations against the executable model. For the temporal specifications, the connection remained weaker.
That weaker connection became an engineering problem of its own. One model-to-implementation conformance test drifted red after production changed and remained broken for days. Repairing the test fixed the instance; the durable response addressed the class. Formal specifications were registered behind a common runner, model-to-spec correspondence became mechanically checkable, and changes to modeled production surfaces began selecting the relevant formal and conformance checks. The checks themselves therefore acquired some of the same drift controls as the models they supported.
The distinction matters. Exhaustive checking establishes properties of a model. Correspondence evidence supports the separate claim that the implementation still realizes the relevant parts of that model. Strong evidence for the first claim does not make the second automatic.
Nor did every formal result receive the same authority. The explicit-state ownership checks participate directly in the engineering environment; TLC execution remains advisory rather than a hard release gate. That asymmetry is deliberate. DocAble adopted formal methods where they made a consequential property easier to state or search, then gave the resulting evidence only the authority its connection to the implementation could support. Structural enforcement handled properties that could be made impossible by construction; state exploration handled dangerous interleavings; temporal model checking handled obligations over executions.
The formal machinery mattered, but representation came first. Before the lifecycle and ownership models existed, I could describe the system's behavior in prose, but questions about legal transitions, competing claims, stale ownership, and eventual termination remained slippery. Once those behaviors had names and explicit structure, properties that had been difficult even to formulate became obvious enough to ask—and sometimes mechanical enough to check. The representation did not merely record my understanding of the system. It changed what I could understand about it.
Software engineering has long exploited a milder version of this effect: a shared vocabulary makes recurring structures easier to recognize, reason about, and communicate. This insight is part of what made the "Gang of Four's" Design Patterns so influential. Gamma and colleagues argued that naming a pattern increases the designer's vocabulary, raises the level at which a design can be discussed, and makes it easier to think about designs and their tradeoffs.** The authors make vocabulary an explicit benefit of pattern names: naming recurring structures lets designers reason and communicate at a higher level of abstraction CITE0 . Models pushed the same idea further in this case. They supplied not just names but structured semantics: once states, transitions, ownership, and temporal obligations had explicit representations, new properties became available both to human reasoning and to mechanical analysis. The representations available to an engineer shape the properties that engineer can readily see and state.
Field note — the map that pointed at a ghost. One model named a code symbol that was later moved and renamed. Nothing invalidated the reference. The model continued to look authoritative, agents continued to reason from it, and the failure surfaced days later during deployment. That incident forced live trace resolution: model-to-code edges were re-resolved against current symbols so a stale pointer failed at the change that broke it rather than downstream.
Evidence — a reasoning surface creates a maintenance obligation. A later audit showed the pointer failure was a class, not a one-off. Re-running closed work against current code found genuine model-to-code drifts that a green definition of done had missed, the prod-blocking pointer among them. Mechanical correspondence checks then turned stale-reference failure into something the environment catches at the change that creates it. Appendix H carries the counts.
Formalizing and instrumenting previously weakly represented seams also exposed live defects that green tests had not. The useful claim is not that "models find bugs." It is that forcing an engineering relation into an explicit representation creates new questions the environment can ask, and in these three cases those questions exposed shipping defects.
The same instrumentation measured its own reach: a traceability tracer made the remaining unmodeled surface measurable and guided later modeling toward the largest gaps. Appendix H carries the run-by-run series and the discrimination that keeps the number honest.
What modeling exposed that green tests missed. Three live defects came into view when previously implicit relations were represented explicitly:
- A cross-runtime exit code one runtime emitted and the other had never enumerated, so a genuine failure was silently misfiled as a generic error.
- Asymmetric cleanup after redelivery — a failure path purged a job's database rows and blobs but skipped the queue structures its sibling path always cleaned, leaking chunks on a rare edge.
- A last-write-wins editor race in which two concurrent saves silently discarded one's work.
Figure 5.3-5 draws the five-rung climb.
Delegation increased as the environment took over work I had previously carried in direct review: models carried system knowledge, while mechanisms carried repeatable admission decisions. A weak model pulled me back into reconstructing the map; weak evidence or controls pulled me back into inspecting outcomes. Human judgment stayed at the unresolved edge. Parts II–IV present the clean method that can now be taught directly; this case shows why those pieces exist and why they did not arrive as one package. The next chapter reconstructs the incidents that moved that edge.
Works Cited
- Ringer, Talia, Karl Palmskog, Ilya Sergey, Milos Gligoric, and Zachary Tatlock. “QED at Large: A Survey of Engineering of Formally Verified Software.” Foundations and Trends in Programming Languages 5, nos. 2–3 (2019): 102–281. https://arxiv.org/abs/2003.06458.
- Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1994.