Until now the doc-gardener example was a single monolithic
orchestrator binary writing synthetic messages directly to SQLite.
That's now obsolete: the feature runs as a true multi-agent flow
where the SynapBus reactor fires subprocess runs for every DM, each
agent is its own reactive subprocess invocation, and follow-up DMs
go through the real MessagingService.Send → dispatcher path so the
reactor picks them up.
Changes:
- cmd/synapbus/main.go: gate the three legacy background workers
(expiry, retention, stalemate) behind SYNAPBUS_DISABLE_*_WORKER env
flags. These workers manage the legacy channel task-auction /
message retention features the doc-gardener demo doesn't use, but
they held the single-connection write pool long enough to wedge
the whole server for interactive sessions. All three are disabled
in the example's start.sh.
- cmd/docgardener/agent.go (new): the per-agent subprocess entry the
reactor harness invokes for every reactive trigger. Reads
message.json from the workdir, routes by SYNAPBUS_AGENT to either
coordinator-kickoff, coordinator-completion, or specialist-work
logic. Writes prompt.txt + response.txt for harness capture. Uses
the admin socket (`synapbus messages send`) for follow-up DMs so
the real MessagingService.Send path fires the dispatcher.
- cmd/docgardener/main.go: adds `docgardener agent` subcommand, plus
helpers freshAPIKey / bcryptHash / absPath / selfPath used by the
spawn flow.
- examples/doc-gardener/start.sh: provisions user + coordinator
agent + algis human agent + approvals/requests channels; the
coordinator is created with trigger_mode=reactive,
harness_name=subprocess, local_command pointing to docgardener
agent, and harness_config_json.env carrying SYNAPBUS_AGENT,
SYNAPBUS_BIN, SYNAPBUS_SOCKET. Specialists are spawned
dynamically by the coordinator at runtime (not pre-registered),
so the demo exercises dynamic agent spawning end-to-end.
- examples/doc-gardener/run_task.sh: collapsed to a 3-line kickoff
that just DMs the coordinator and polls algis's inbox for the
coordinator's FINAL: reply. Everything else happens via the
reactor.
Verified end-to-end in Chrome on a fresh instance:
- 4 agents registered (coordinator + 3 specialists dynamically
spawned by the coordinator on receipt of the first DM)
- 7 reactive_runs + 6 harness_runs across the goal lifecycle:
algis → coordinator (kickoff, 624ms, builds goal+tree+spawns)
coordinator → docs-scanner (claim task 2)
coordinator → cli-verifier (claim task 3)
coordinator → drift-reporter (claim task 4)
docs-scanner → coordinator (DONE task=2)
cli-verifier → coordinator (DONE task=3)
drift-reporter → coordinator (DONE task=4, coalesced)
- Web UI Agent Runs page shows all 7 runs with the real
"DM from X" trigger lines and correct sender/receiver chain
- Goal ends at status=completed with all 3 leaf tasks at status=done
- Each specialist run posts a real subprocess artifact to the
goal channel (#finding, #verified, #summary) and appends a real
reputation_evidence row keyed by config_hash.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>