# ADR 0017: Marvin, the orchestrator's memory ## Status Accepted. ## Context Ferryman coordinates workers well. A worker that dies is recovered by ADR 0011: its claim is released, another machine picks the task up, and nothing is lost because everything a worker needs is in the order. The orchestrator has none of that. It is the agent that decides *what the orders should be*, and when it stops — context exhausted, session ended, subscription spent — the project does not continue with a different orchestrator. It restarts, badly. The owner's words: *"when the main orchestrator runs out of tokens, no other orchestrator can take over in a meaningful way, it kills me 3 days a week."* Three days a week is not an edge case. It is the normal operating condition of the product, and it is unaddressed. `ferry loadmem` was built for this and does not solve it. It prints the memory bank, the durable log and the agent profiles — everything the *project* knows. What it cannot print is what the orchestrator knows and nothing else does: - the current objective, and what it is being traded against - what is in flight, and why each thing sits where it does - decisions that were load-bearing but never ADR-worthy, and the reason behind each - the human's standing constraints, which are learned by being corrected - what is waiting on the human rather than on a machine - what was tried and rejected, so the next orchestrator does not spend its first hour rediscovering it None of that is in the channel. It is in a context window, and a context window is the one component of this system with no durability story at all. ## Decision ### Marvin is the memory, and machines take turns holding it `/marvin/brief..json`, named after its only writer, like every other record here — so two orchestrators can never produce a conflicting edit and a successor can read the outgoing one's brief while writing its own. It holds an objective, a deadline if there is one, and six free-text sections: constraints, in flight, decided, rejected, waiting on the human, and next. Free text on purpose: the value is in the reasoning, and a schema that forced the reasoning into fields would keep the fields and lose the reasons. It is signed and verified exactly as every other channel artifact is, against the roster, and for the same reason `memory` gives for signing a profile: a brief is not a document, it is **prompt text**. It is written to be pasted into a fresh orchestrator as its opening context, which makes an unsigned one an injection vector any peer with write access to the synced folder could plant. ### It is written continuously, not at handoff This is the part that matters, and it is the same insight as `ferry-deadman`: **running out of context is never a graceful event, so the handoff cannot be an event.** There is no moment at which a dying orchestrator reliably gets to write a summary. It may simply stop mid-sentence. So the brief is updated as work happens — after a decision, after a dispatch, after the human says something that changes the standing constraints. `ferry marvin brief` therefore touches only the sections it is given: an orchestrator recording one decision must not have to restate the other five, because the version that costs six paragraphs is the version that stops being written. When updates stop, the last one is already current. The staleness of the brief is itself the signal: an orchestrator whose brief has not moved while its fleet has is an orchestrator that is gone. ### `ferry marvin resume` produces the handoff, not the raw record A successor should not have to read JSON and assemble a picture. One command prints, in the order a new orchestrator needs them: the brief and how old it is, who wrote it and whether that signature verifies, the roster, work in flight taken from the channel rather than from the brief, and what is waiting on the human. Work in flight is read from the channel on purpose, so a stale brief cannot hide a task — and the two disagreeing is itself information. ### It is a memory, not a machine, and one machine holds it at a time The thing that has to survive is not a machine and not a model. It is what the orchestrator knows. So Marvin is the memory, and holding it is a lease rather than a title: taken with `ferry marvin take`, kept alive by the act of writing to it, and takeable by somebody else once it has gone quiet for thirty minutes. That gives the property the whole feature exists for - **the project carries on with a different machine, or a different model, holding the same memory and continuing the same thought** - without ever having two orchestrators issuing orders into one channel, which is the failure this replaces rather than a new one to tolerate. Each holder still writes its own file, because one-writer-per-path is the rule the entire channel rests on and two machines editing one file is the conflict this project structurally does not have. Those files are not separate briefs; they are pages of one memory, and `resume` reads them as one. `take` refuses while the current holder is still being heard from, and `--force` exists for the case the rule cannot see: a machine a person knows is gone but whose last heartbeat is recent. `release` pushes the heartbeat back rather than deleting the file, because the succession is part of the memory and a hole in it is not an improvement. Named for Douglas Adams' Marvin: a mind that carries on regardless of which body it is in, and remembers everything. ## Consequences **The orchestrator becomes recoverable, which is what the rest of the product already assumes.** ADR 0011 recovers a dead worker; nothing recovered the thing that issues the orders. This closes the gap at the top. **It is honest about what a successor inherits.** A brief carries a signature and an age, and the age is never buried: past four hours `resume` says so in words, because a successor reasoning about a four-hour-old brief must behave differently from one trusting it as current. **It costs the orchestrator discipline.** A brief that is not updated is worse than none, because it will be trusted. The mitigation is that updating it is cheap and the age is always shown — a stale brief announces itself rather than lying quietly. **It is not a transcript, and must not become one.** The temptation will be to dump everything. A successor that has to read four hours of history has not been helped. The brief is the state of the world now, plus the reasons that are not reconstructable from it. ## What this is not Not a second orchestrator running in parallel — that is [the continuity proposal](../ORCHESTRATOR_CONTINUITY_PROPOSAL.md), which is about failover of *execution* and is a separate and larger decision. This ADR is only about making sure that whatever takes over, human or machine, knows what was in the head of the thing that stopped.