Daemon and Agents¶
greatminds launch starts the configured agent windows from the environment
where greatminds is installed, for example greatminds launch --target tmux.
Each window is defined in coordination/coord.yaml with:
- window name
- role
- tool (
claude,codex,cursor,cline,gemini,openhands, orbash) - mode (
chat,loop,dashboard,logs,staged, ordriven)
The role's lifecycle is declared in the packaged schema copied to
.greatminds/schema.yaml:
interactive: human-paced chat.ARCHITECT-PLANNERis the normal user-facing planner.self-loop: an autonomous watchdog loop.MAINTAINERuses this to recover dead agents, restart coordd, and escalate FSM stalls without waiting for USER.driven: no persistent agent loop. The pane is idle between turns;coorddruns one turn when an inbox, queue, or stand-state event lands.
Driven dispatch requires both the schema lifecycle and the installed
coordination/coord.yaml window mode to be driven.
coordd¶
coordd watches .greatminds/ for inbox, queue-file, and stand-state
activity. It does not own the task FSM and does not decide task transitions.
Its job is turn delivery: when a producer moves work into another role's queue,
the consumer can react immediately.
On Linux, coordd arms an inotify watcher. New inbox files under
.greatminds/inbox/<role>/ and new task files landing in watched queues trigger
the owning role's event path. For non-driven roles, the wake mechanism is
selected from .greatminds/schema.yaml under event_wake.by_tool, keyed by
the role window's coordination/coord.yaml tool: value:
codexandcursor:coorddfinds the role's deepest sleeping descendant and sendsSIGINT. That interrupts the long sleep wrapper so the next tick starts immediately.claude:coorddsends the configuredtmux send-keystext plus Enter to the role's tmux pane. The default text is defined inevent_wake.tmux_send_keys.keys.
For driven roles, coordd starts one turn instead of waking an existing loop:
claudedriven roles run oneclaude -p/ resume turn with the rendered role bootstrap file using an explicit user environment. The daemon setsHOMEto the OS user's home directory, ensures$HOME/.local/binis onPATH, and resolves the Claude binary by absolute path when possible. This matches non-interactive subprocess requirements: Claude Code reads first party credentials from$HOME/.claudeand is commonly installed under$HOME/.local/bin.codexdriven roles run one freshcodex app-serverstdio process for the turn; the app-server thread id is persisted for continuity.cursor,cline,gemini, andopenhandsdriven roles run one headless subprocess turn using the tool's own one-shot CLI mode. Cursor turns are wrapped in the samesystemd-run --user --slice=cursor.slice --scoperesource boundary as interactive Cursor panes and include--trustin print mode. Gemini driven turns include--skip-trust. OpenHands driven turns require theopenhandsCLI settings and LLM provider to be configured beforecoorddstarts the turn. These adapters are stateless from greatminds' point of view: the full role bootstrap is supplied each turn, and the tool's machine-level auth/configuration must already be valid for the OS user runningcoordd.
Driven roles do one tick, then exit. They do not schedule long sleeps or run a
persistent /loop; their next turn comes from the next inbox, queue, or stand
event.
coordd also writes a best-effort chronological driven-agent event stream to
.greatminds/.events/driven.ndjson. The stream is read-only operator
observability, not FSM authority: task files, locks, stand state, and turn logs
remain the source of truth. A fresh tmux launch includes a role-less logs
window that runs greatminds driven-log --follow and shows accepted turns,
pending markers, completions, retries, and errors in color.
greatminds launch --target vscode writes VS Code tasks for the same operator
surfaces: dashboard, driven log, coordd foreground, agent status, agent tools,
stand status, and stand profiles. The vscode-extension/ package provides a
VS Code cockpit that calls the same CLI backend.
This reactive path replaces short idle polling for normal queue and inbox changes. Reaction time should be the daemon watcher interval plus one driven spawn or wake signal, not a role's fallback sleep value.
Stand availability is also treated as a dispatch event. When coordd's own
auto-deploy thread returns the singleton to free after a failed deploy, it
immediately reconciles driven backlog. External stand commands such as
stand up and stand release write a .stand/available-*.yaml event so the
watcher re-drives roles whose tasks were already parked in stand-dependent
queues. A separate level-triggered backstop handles the case where coordd
starts after the stand is already free: while state=free, no active lease is
present, and stand-consumer queues still contain work, coordd periodically
re-drives only those consumer roles. The same startup and periodic hook also
cleans a declared Vite dev-server port when the stand is free and no lease owns
it.
coordd does not push visual status markers into chat panes. Those markers are
per-agent utterances: after a successful task move, task block append, or inbox
send, the agent ends its own chat reply with the matching marker line.
Event-wake troubleshooting¶
If a role does not react to new work, check these in order:
- Confirm the daemon is running for the project with
greatminds daemon status. - Confirm the role exists in
coordination/coord.yaml, has the expectedtool:, and has a live agent registry entry. - Confirm the role's schema lifecycle and
coordination/coord.yamlmode agree with the expected model. Driven roles require both values to bedriven. - For a driven role, inspect coordd logs for the driven spawn result and check
the per-role run lock under
.greatminds/.locks/. - Confirm
.greatminds/schema.yamlmaps that tool inevent_wake.by_toolfor non-driven roles. - For non-driven
codexorcursor, inspect whether the agent is actually inside a sleep descendant.coordddoes not signal the agent process itself when no sleeping child exists. - For non-driven
claude, confirm the tmux session and window name matchcoordination/coord.yaml. Chat-mode wakes are rate-limited byevent_wake.tmux_send_keys.rate_limit_seconds, so a burst of messages may coalesce into one prompt. - For driven
claude, rungreatminds daemon doctor --project-dir "$PWD". It probesclaude -pin daemon-equivalent env and reports expired OAuth credentials, missing refresh tokens, and missing captured agent env files. Repair auth withclaude setup-tokenorclaude auth loginas the daemon's OS user, then restart the daemon. - Run
greatminds watchdogto check dead pids, stale heartbeats, and orphaned intents. - Run
greatminds agent status [ROLE]to inspect the recorded pid, liveness, session id, venv, heartbeat age, and input socket without reading registry files by hand.
Visual event markers¶
Operators can scan live tmux panes by the marker at the end of an agent reply.
The templates live in .greatminds/schema.yaml under visual_events; docs and
prompts describe the contract, but the schema is the source of truth for the
exact emoji and markdown shape.
CLAIMED: an agent moved a task into an implementation or ownership queue it is taking over.FINISHED: an implementer moved completed work to the next review or test queue.ACCEPTED: a reviewer moved the task toverified.REJECTED: review or test feedback sent the task back for more work, or a failure/partial result was recorded.SENT: an agent sent an inbox message to another role.
Because these are emitted by the acting agent, they appear only when the agent
successfully completes the CLI action and replies. Daemon status belongs in
greatminds dashboard and the driven event log, not in chat-pane overlays.
pty launch¶
The launcher wraps agent tools in a pty and records an input socket in the
agent registry. The socket lets coordd send actual input to the agent process
instead of writing display text to a terminal.
Heartbeats¶
Most CLI calls update the caller role's heartbeat as a side effect. Driven
Claude and Codex turns also refresh the heartbeat from driver-observed progress:
subprocess output, Codex app-server activity, and source worktree writes. This
keeps long active turns from looking stuck merely because the agent has not made
another greatminds CLI call.
Driven subprocesses use a progress-based timeout. A turn can run for an extended period while it is producing output or changing the lease worktree; coordd kills and retries only after the idle progress window is exceeded, or after the larger absolute ceiling.
Watchdog reports stale heartbeats, orphaned intents, dead pids, and stale tasks:
greatminds watchdog