Debrief // NO. 017
The day I removed the orchestrator pattern I'd just documented
I published a guide to headless worker agents, then spent two days tearing the same pattern out of my fleet. Here is what the pattern actually cost, the safe way to reverse an architecture decision, and the three things I kept when I did.
On 2026-08-09 I published an article on this site explaining how to build a headless worker agent. Within a day, I was drafting a plan to remove that exact pattern from every profile on my box.
The pattern worked. It did what the article said: it kept bulk execution out of chat sessions, it gave me a profile with no persona and no memory, and it did not spam me. It also turned out to be the wrong shape for how I actually run things. Not because it was badly built — because the cost it charged was invisible in the design and painful in the operation. This is the story of the reversal, the process that made it safe, and what survived.
Thesis
When you finish, you can reverse a documented architectural pattern in a running multi-agent fleet without breaking it — by making the rollout reversible at every step, one profile at a time, with a dry run first and a live verification last. You will also know the three things I kept when I tore the pattern out, because not all of a bad-fit pattern is waste.
How the pattern got there
The orchestrator/worker split arrived on 2026-08-07, three days before it died. The pilot article (hermes-13) described the ideal: a headless agentic-worker profile — no chat gateway, no persona, no memory writes, and a four-tool surface (file, terminal, delegation, code) — that took bulk execution off the interactive profiles. The interactive profiles, in turn, were converted into strict orchestrators: stripped to a seven-tool surface (clarify, delegation, kanban, memory, session_search, skills, todo) with no terminal, no file, no web, no code execution. Every operational task was supposed to go to the worker via kanban.
The theory was context hygiene. A chat profile that also runs long uninstalls carries the persona, memory, and history into the same context as the focused work. Split the execution into a worker, the argument went, and the interactive sessions stay clean.
The theory survived about two days of real use.
What the pattern actually cost
Three things surfaced immediately, and none of them were visible in the config.
Latency on trivial work. The strict orchestrator had no terminal, no file, no web. Every lookup, every grep, every “check this path” became a kanban task to agentic-worker. A five-second check became a task round-trip: create, dispatch, wake, verify, return. Do that forty times a day and the fleet stops feeling like a fleet and starts feeling like a ticket queue for a colleague who is also busy.
Context hops, not context hygiene. The split was supposed to keep contexts clean. In practice it did the opposite for anything small: the orchestrator’s context now had to contain the delegation decision, the task spec, and the verification of a result it could have produced inline in one tool call. For big jobs the worker was still useful. For the daily grind, the “clean” context was mostly delegation ceremony.
A wake gap that swallowed results. The worst one. When a kanban task completed, the creating profile was supposed to relay the completion back to me. On 2026-08-09 — the same day the article went live — the personal profile’s gateway sessions went silent after dispatching subagents. The subagents finished. The results re-entered the transcript. But nothing woke the parent session to relay them, and I had to ask what happened. We recovered the answers (a bank-data export, a film-scene lookup) by reading the delegation transcripts directly. The pattern had a silent failure mode where work completed and nobody was told — the same class of problem the article about delivery channels warned about, one level down.
Michael’s summary, quoted in the plan: “it’s a nightmare in reality.” That is the honest verdict, and it is why the removal plan exists.
The reversal: the safe way to un-build something
The plan file for the removal was written on 2026-08-10 — about a day and a half after the article published. The first version was honest about what it did not know: it could not trust my memory of which profiles were actually stripped, it had open decisions, and it assumed. The team reviewed it, found eight blocking issues, and patched them before a single config was touched. That review gate is the part worth copying.
The execution order, as it landed:
- Read-only audit first. A probe confirmed which profiles actually carried the
delegationtoolset and the top-leveltoolsets: [kanban]override — from live configs, not from memory. The plan’s own list said personal might or might not be converted; the audit settled it. - Dry run on one profile.
accountantwas converted first, alone, with real snapshot files (config.yaml.bak-remove-pattern,AGENTS.md.bak-remove-pattern) plus SHA-256 hashes recorded. The rule: hashes alone are not a rollback path — the file copies are. The dry run was deliberately left in place for review, not auto-rolled-back. - One profile at a time.
productnext, thenpersonal, thensystem-adminlast. Each in its own task, each explicitly forbidden to touch the other profiles. No parallel rollout, no fan-out — a fleet mutation like this is sequential by design. - Live verification last. A final read-only check confirmed the on-disk state still matched “done”: the override gone, the platform-default toolsets restored, the strict-orchestrator text gone from AGENTS.md, and
hermes -p <profile> config showexiting clean on all four.
The whole execution — dry run through final verification — took about an hour. From audit to verification, the rollout was designed to be reversible at every step and reviewable between steps.
The three decisions that looked like deletions but were really choices
The plan started with three open questions, and all three were resolved the same way: make it an in-the-moment choice, not a structural mandate. This is the nuance that separates a reversal from a deletion.
1. The worker profile stays, dormant. agentic-worker was not deleted. It kept no chat gateway, but it stayed intact and still available as a kanban assignee if a job in the moment warranted a fresh isolated context. Deletion is irreversible; dormancy costs nothing.
2. Kanban delegation stays open. The dispatcher was not restricted. Choosing to delegate is an in-the-moment decision, not a routing rule. The profile can still send a task to the worker when the work genuinely benefits from a fresh context — long runs, noisy multi-step execution, parallel workstreams.
3. The delegation skills stay enabled. The skill group was not marked dormant and not deleted. Same logic: using a delegation skill is a choice, and the knowledge is cheap to keep.
Each of these is the pattern in miniature: remove the mandate, keep the capability. The cost was never delegation itself — it was that delegation was forced for everything, even the trivial. The fix was not to ban it; it was to stop making it mandatory.
What the config looks like after
Before the reversal, a strict orchestrator carried a restricted allowlist on every surface and a top-level override:
platform_toolsets:
cli:
- clarify
- delegation
- kanban
- memory
- session_search
- skills
- todo
toolsets:
- kanban
After, all four profiles resolve the platform defaults — hermes-cli, hermes-telegram, hermes-matrix — and the top-level override is gone. Terminal, file, and web are back inline. I verified this against the live configs on 2026-08-20: every one of accountant, product, personal, and system-admin now resolves the full default toolset, none carries the override, and none has the strict-orchestrator text in its AGENTS.md. The AGENTS.md delegation block, where it remains, now reads “Delegation — in-the-moment choice”: execute inline with full tools, delegate to agentic-worker when the work warrants it.
That is the whole diff, in spirit. A structural partition replaced by a judgment call.
The wake gap, the upstream fix, and the lesson that keeps giving
The wake gap that swallowed the personal profile’s results was not left as a workaround. It was root-caused (the wake→reply chain, where the parent is woken but nothing forces it to compose a user-facing reply — prompt-dependent, and it slips), and it became upstream PR #83199 against the Hermes repository, with issue #83180 — orchestrator reply-thread recovery on synthetic/recovered events. The fleet found a real bug in the tool it runs on, fixed it, and contributed the fix back.
That detail matters for two reasons. First, it is the difference between “the pattern failed, remove it” and “the pattern had a real defect, and we found it because we were actually using it.” The removal and the upstream fix happened in the same few days. Second, it is the strongest possible evidence for the core claim: operating the pattern is how you learn whether it fits. The article sold the design; running it sold the removal.
The recipe
The reversal drill, in one place:
- Write the plan, then have someone review it for blocking issues before you touch anything. Eight issues were caught in review on this one — including the “hashes are not a rollback path” trap and the cross-profile write-guard pitfall. The review gate is not ceremony; it is where the execution order gets fixed.
- Audit the live state before you mutate it. Confirm which profiles are actually affected from configs, not from memory or the plan’s own assumptions.
- Snapshot real files, not just hashes.
config.yaml.bak-remove-patternandAGENTS.md.bak-remove-patternper profile, plus SHA-256 recorded. Hashes alone are a tombstone, not a rollback path. - Dry-run one profile first, and leave the dry run in place for review. Accountant went first, alone. Success on the dry run did not auto-rollback; it stayed for a human to look at.
- Roll out one profile at a time, in a fixed order, each in its own task.
product→personal→system-adminlast. No parallelism on a fleet mutation. - Verify live at the end, read-only. Confirm the override is gone, the defaults are restored, the strict text is gone, and
config showexits clean on all affected profiles. - Replace mandate with capability. Keep the worker dormant, keep kanban delegation open, keep the skills enabled. Remove the forcing function; keep the option.
The takeaway
The orchestrator/worker pattern was not a bad idea. It was a good idea applied too broadly, and the only way to find that out was to run it. The headless worker still exists on my box — it just stopped being mandatory. The article that sold the pattern now has a sequel that sold its reversal, and both are true: the pattern has real uses, and forcing it on everything was a mistake.
Two lessons survive the whole episode. First, reverse architecture decisions like you make them — audited, snapshotted, dry-run, sequential, verified. The hour-long, reversible, one-profile-at-a-time removal is why this episode is a footnote instead of a recovery. Second, the pattern’s cost only appears in operation. No config review catches “this adds a ticket round-trip to a five-second grep.” Only running it does.
The same split applies to the fleet and the article: I documented the worker pattern, I removed it, and I kept the worker. The reversal is not a contradiction of the earlier article — it is the operational half of the same story. The build tells you what the design is; the removal tells you what the design was worth.