The coordinator now reaches SynapBus's MCP endpoint directly from
inside the Gemini session. wrapper.sh's coordinator branch is a pure
pass-through — no more JSON-plan parsing. When the coordinator runs,
Gemini connects to /mcp with the coordinator's own Bearer API key and
calls `create_goal`, `propose_task_tree`, and `send_message` as native
tools. Goal rows, task trees, and DMs all land in the DB in one
in-session flow.
- start.sh mints a fresh API key for goal-coordinator via
`agent revoke-key` and substitutes it into configs/coordinator.json
(plus the port) at apply_config time.
- coordinator.json declares the synapbus MCP server in mcp_servers;
the subprocess harness already writes .gemini/settings.json from
that array, so gemini picks it up automatically.
- GEMINI.md rewritten to instruct the model to call MCP tools
instead of emitting a JSON action blob. Stdout is explicitly
discarded; every reply goes through send_message.
- wrapper.sh coordinator branch is ~15 lines: invoke gemini, log,
exit. Inspector + critic keep the legacy JSON-plan pattern since
they're workers with fixed contracts.
- SYNAPBUS_KEEP_WORKDIR=1 preserves per-run workdirs for debugging
MCP traces, gemini output, and materialized configs.
- Reactor checkPendingWork now fires after subprocess run completion
(previously only K8s poller hit this path). The synthetic
coalesced trigger uses a `__coalesced__` sentinel instead of
`system` so it bypasses the FromAgent=="system" dispatch guard.
Verified e2e (with rate-limit-induced retries):
- TRIVIAL: "what is 2+2?" → coordinator send_message(algis, "4")
- INFEASIBLE: "Transfer \$50…" → coordinator
send_message(algis, "CANNOT: …")
- SINGLE-STEP: 3-node task tree materialized in goal_tasks,
TASK JSON forwarded to generic-inspector → critic-auditor chain.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>