Skip to content

v2026.05.20 — Autonomous mind v2: missions, arbiter, cooperative preemption

Choose a tag to compare

@elophanto elophanto released this 20 May 09:10
· 207 commits to main since this release

Autonomous mind v2

Triggered by observing the previous mind loop on a single stuck goal for 36 hours, logging "bounded source-of-truth reconciliation" every wakeup. Root cause was structural: the executive loop was a three-branch router (active goals → planning goals → dream) where one wedged active goal black-holes attention. Full design doc: docs/75-AUTONOMOUS-MIND-V2.md.

What's new

Missions tier — durable operator-defined drives that the mind works toward across many goals. New missions table + goals.mission_id. CRUD via MissionManager (running-sum momentum with 7-day half-life decay, neglect-ranked listing). Five tools (mission_list/create/status/touch/update). elophanto mission CLI: list / show / touch / pause / resume / retire. Zero hardcoded defaults — operators define their own via the setup wizard, identity config, or the CLI.

Scored-candidate arbiter (opt-in) — replaces the if/elif decision tree with five candidate sources (workable_checkpoints, mission_momentum, dream, reflexes, external_signals stub) → linear scoring → top-K menu → LLM picks one. Per-wakeup [arbiter] log lines for audit. Off by default; flip autonomous_mind.arbiter.enabled: true to activate.

Cooperative preemption_PrioritySemaphore signals lower-priority holders when a strictly higher-priority caller arrives; the agent yields at a safe checkpoint between rounds (no mid-tool-call interruption). Mind/AutoLoop treat preempted runs as "reschedule, don't bill"; scheduler records `status='preempted'`. Heartbeat moved from priority 1 to 3 — was punching scheduled cron work mid-flight.

Stop-the-bleeding hygiene — `_workable_goals_status` correctly classifies a goal whose only remaining checkpoint is `active` >12h as stuck (not workable); surfaces via `[STUCK-CHECKPOINTS]` in the mind prompt. Periodic `llm_usage` flush (`CostTracker.flush` existed but had no caller — `llm_usage` table sat empty for entire process lifetime, hiding tail-loop cost).

Upgrade path 🆕

Existing installs: `./update.sh` does the whole thing — git pull (with stash + restore), Python deps refresh, browser bridge rebuild, `elophanto config migrate` to patch your existing `config.yaml` with new sections without losing your settings (surgical inserts under existing parent blocks, idempotent, `.bak` backup written before edits).

This is the killer feature for this release: before today, getting new config sections required overwriting your config via `elophanto init`. Now `./update.sh` preserves your existing values + comments + adds what's new.

Fresh installs: `./setup.sh` unchanged; the wizard now opt-in prompts for operator-defined missions.

Post-live UX fixes

  • Arbiter prompt rewrite + new `_derive_action_summary` so the dashboard action log shows tool calls (`tool_a + tool_b + tool_c`) instead of LLM meta-narration (`"Picked candidate 2 because…"`).
  • Dashboard CSS guards (explicit `width: 1fr`, `overflow-x: hidden`, `scrollbar-gutter: stable`) so chat content can't render narrower than the panel.
  • Mouse-tracking disable interval 500ms → 5s so Shift/Option+drag selection works in most emulators.

Tests

31 arbiter + 19 mission_manager + 4 cost-flush + 2 stale-checkpoint cases added. 239 focused tests green. Ruff + mypy clean.

Commits in this release

  • `5113f47` G: cooperative preemption + heartbeat priority fix
  • `a80afb1` Autonomous Mind v2: missions tier + scored arbiter + update path
  • `79441df` Fix CI: lint (ruff) + type (mypy) errors in v2 commit
  • `364b5a8` Release v2026.05.20: autonomous mind v2

Full diff: v2026.05.19...v2026.05.20