0067 — The Supervisor is deleted
- Status: Accepted 2026-10-18. Built in the same PR (ADR-0004: recorded at decision time). Supersedes ADR-0066. Superseded in part 2026-10-18 by ADR-0068: the What keeps working bullet on the idle-Driver check-in — it is retired, not "still the Driver waker".
- Date: 2026-10-18
- Deciders: Gera (they/them), the same day the Supervisor was switched off: "the supervisor I'm convinced we should probably just delete it. I feel like it adds more friction than value, especially since models are just so good… If it's in GitHub, we could always reference back to it. But as of now, I don't want any sort of polling or jobs in the background that can consume tokens. I want everything to be clean." And on what stays: "I do like the driver. So I wouldn't want to delete the driver."
- Systems:
- the agentflow Supervisor:
supervisor/, launchdcom.propflow.agentflow-supervisoron the mini, rung 3's daemon in ADR-0003's supervision ladder. Deleted. - the relay (
relay/): four write routes whose only consumer was the Supervisor now refuse. - CI (
.github/workflows/ci.yml,ci/run-test-shard.sh) anddeploy.sh: relay only. SYSTEMS.md: theagentflowandred-mainentries.
- the agentflow Supervisor:
Why
The Supervisor was switched off at 2026-10-18 01:35:46Z after a late-boot kill loop (fixed in #405, recorded in ADR-0066). Gera then decided it should not come back as a running service. Sessions stay up on their own now, a daemon that polls every minute is a standing cost, and the code is still in git if it is ever wanted. The Driver stays.
So this removes the code instead of leaving a disabled service and a build on disk that someone could start by accident.
What was deleted
- All of
supervisor/: its source, tests,bin/supervise,bin/redmain-claim.py, the verification scripts, the launchd plist templatesupervisor/deploy-com.propflow.agentflow-supervisor.plist, andsupervisor/control-13-autocompact.sh. - Its CI steps: install, typecheck, build, and the
supervisor/tests/**test glob. The one required check,ci / result, still runs ESLint, the gate suite, and the relay's typecheck, build and tests. - Its half of
deploy.sh: the build, thekickstart, and the "freshsupervisor upline" check.deploy.shnow builds and restarts the relay and checks/health. - The relay's request writers for it:
relay/src/intake/intake.ts, and the request-writing halves ofrelay/src/preview/devPreview.tsandrelay/src/audit/audit.ts. relay/tests/mirrorParity.test.ts. It compared the relay's sanitiser with the Supervisor's copy, and there is no longer a copy.
What the relay now refuses, and why
Each of these routes used to write one request file under ~/.claude/jobs/ and answer ok: true. The Supervisor was the only thing that read those files. If the routes kept writing them, they would keep reporting success for work that will never happen. So each one now answers 410 Gone with a plain sentence saying what stopped and what to do instead (relay/src/retired.ts), and writes nothing:
| Route | What it did | What it says now |
|---|---|---|
POST /api/intake |
filed a job; the Supervisor minted a Driver for it | filed jobs are no longer started; start the work from a Claude session |
POST /api/adopt |
filed a job for a session that already existed; the Supervisor minted only its Driver | nothing assigns a Driver to an existing session; start one from inside that session |
POST /api/preview/dev |
asked the Supervisor to start or stop a worktree's dev server | previews are no longer started or stopped from the page |
POST /api/audit |
asked the Supervisor to run a headless deep check | deep checks are no longer run from the page; run the agent-audit skill in a session |
The routes stay registered rather than returning 404, because a 404 looks like a typo or an outage and doesn't say why. relay/tests/routeEnumeration.test.ts lists them apart from the real write routes, and relay/tests/retired.test.ts calls each one over HTTP and checks the 410 response and that nothing was written.
One more relay behaviour changed. A Supervisor alarm tied to a condition (a ledger row carrying supervisor_alarm_condition, such as dock-frozen or task-repo-unusable) used to be acknowledged by a click on /agents and left open. The Supervisor would close it once the condition ended. Nothing re-checks a condition now, so an acknowledged row would stay open forever. A click now resolves it like any other block (relay/src/blocks/resolve.ts). On 2026-10-18 the mini's ledger held 5 open sup-* rows (2 of them condition-backed). They can be answered on /agents to clear them.
The relay keeps reading what the Supervisor used to write, because those files are still on disk and other things still write to them: task.json and task events (Drivers write them), the block ledger including old agentflow-supervisor rows, compaction markers (the context-budget hook writes them), the red-main claim file (now normally absent, so it reads "nobody holds it"), past deep-check results, and the last dev-server state.
What keeps working
- Drivers. Starting one (
/driver,start-operator), the dock, the setup table, sub-agents,blockedraises and the Driver's own judgement are all unchanged. Drivers still writetask.jsonand task events. - Tasks and the board. The relay serves the roster, fleet health, the block ledger, the feed, the ledger, the Systems tab and the live terminal view, all as before.
POST /api/blocks/resolve,/api/ask,/api/messageand/api/blocks/starstill write. - fleet-medic (local-bin, every 300 s) still relaunches a leased session whose host died, unwedges a stuck host, and moves a session off a spent seat.
- Agent Smith and its Temporal watcher. A lane armed on Temporal still has its watcher
--resumethe same conversation. Smith's channel-alert lane still handles red main (see below). - The idle-Driver check-in. nudge's Driver check-in, armed by
watcher-doctor, is still the Driver waker. ADR-0035 had planned to hand that job to the Supervisor'sidlewake.ts. That plan is void. - The idle reaper (
session-cap expire) and the context-budget hook's own compaction trigger. Neither depended on the Supervisor.
What is gone for good
- Driver revival and minting. Nothing respawns a dead Driver into
op-<task>, and nothing gives a Driver to a task that has none. A Driver that dies stays dead until a person or a session starts a new one. - Intake minting. Jobs are not started from /agents (see the table above).
- The answer bridge.
answers.tscopied clicks on a docs.propflowai.co decision page (Cloudflare KV) into the block ledger. It is gone, so a question answered on such a page shows as answered only once the session that asked it runsblocked resolve. Agent Smith's decision-block driver still polls the answer store and wakes the asker (SYSTEMS.mddecision-blocks), so the asker still hears about the answer. Answers given on /agents are not affected:POST /api/blocks/resolvewrites them straight into the ledger. - The Supervisor's auto-compaction: the sweep that typed
/compactinto hot, idle sessions and checked the transcript to confirm it worked. The context-budget hook and nudge's self-compact are separate and unaffected. - Mail and idle wakes: waking an idle session that has unread mail, rescuing orphaned mail from a dead session's inbox, the idle-Driver wake (
idlewake.ts), and the quiet-stop wake (quietstop.ts, which fired when a Worker had been silent for 5 minutes). Mail parked for an idle session waits until that session next drains its inbox. - Red-main fixer minting. Nothing takes the single-owner claim or mints a fixing Driver, and the
BRIDGE CLAIMSlack mirror stops. Smith's channel-alert lane stands down only when a live owner holdsclaim.json. With no claim on disk, it opens its own fix PR. That is now the path. - Release and exit of finished tasks (
releases.ts,exits.ts). A finished task's loop and session are not closed for it. They close themselves, or the idle reaper ends them. - Dev-server reaping (
devservers.ts). Dev servers are not started, stopped or reaped for anyone. - Its alarms:
escalate()and every alarm kind it raised, including frozen dock, duplicate driver records, silent watcher, orphaned mail, stuck inbox, respawn cap, red-main mint cap or refusal, anddriver-never-registered. Rows it already raised stay on the ledger. - The
supervisor loadedsignal on the Systems tab, and thered-maincatalog entry's signals. That entry is markedsuperseded.
Where the code is
Nothing is lost. The last commit on main that contains supervisor/ is d77b030, the merge of #406, which is this PR's base. If another PR touching supervisor/ merges first, it is the parent of this PR's merge commit instead. git show d77b030:supervisor/src/index.ts reads it, and git log -- supervisor/ has its full history.
On the mini, supervisor/dist/ and supervisor/node_modules/ are gitignored, so they stay on disk when the deploy checkout moves past this PR. They are safe to delete. start-operator --adopt reads CRITERION_UNSET from supervisor/dist/tasks.js, but it has a built-in fallback for when that file is missing. The launchd label is still disabled, and on 2026-10-18 the plist was no longer in ~/Library/LaunchAgents.
Bringing it back
- Revert this PR. That restores
supervisor/, its CI and deploy steps, the relay's four write routes, and the condition-backed alarm rule together. Don't restore only part of it: the relay would then accept work nothing does, or a Supervisor would re-raise alarms the relay had closed. - Follow ADR-0066's "Turning it back on" order. Build before you bootstrap, prove the new build is the one on disk, then
launchctl enableandbootstrap. If the plist is not in~/Library/LaunchAgents, copy it there first fromsupervisor/deploy-com.propflow.agentflow-supervisor.plist. - Put the
supervisor loadedsignal back on theagentflowentry in SYSTEMS.md, mark thered-mainentryactiveagain, and write an ADR that supersedes this one.
Options not taken
- Leave it off, keep the code. This is ADR-0066's state. Not taken: Gera wants nothing polling in the background, and a disabled service plus a build on disk can be started by mistake. Git keeps the code either way.
- Keep the relay routes writing their request files. Not taken: every one would answer
ok: truefor work that never happens. This repo refuses false successes everywhere else. - Delete the four routes outright (404). Not taken: the web page and any script still calling them would get an answer that looks like an outage and doesn't say why.