Skip to content

Morpheus

Capabilities/architect subsystem removed (PR #611, 2026-06-22). The capability-truth ledger, capability probes, architect scheduler, and remediation dispatcher/playbooks were deleted as idle dead-weight (capability_probes.py, capability_truth.py, architect_scheduler.py, remediation_dispatcher.py, remediation_playbooks.py and their runtime wiring). Only the Pending Approvals subsystem survives from that lane — the telegram_approval.py / TelegramApprovalService approval queue, the morpheus-pending-approval schema, the slimmed GET /v1/capabilities/snapshot (same shape, truth/scheduler/remediation now empty constants), and the presence-only /capabilities chat command. The other Morpheus lanes below (memory consolidation, troubleshooting probes, self-edit, endless dreaming / todo drain) are unaffected.

Morpheus is Steelmoth/Moth’s autonomous reliability and self-improvement subsystem. It is not one service; it is a set of runtime hooks, probe loops, approval gates, plan artifacts, memory helpers, and optional Codex-backed repair flows.

The runtime wiring lives in runtime.py. Startup can trigger memory consolidation, troubleshooting probes, and endless dreaming when the relevant feature flags allow it. docs/morpheus/09-config-flags.md is the first place to check the operator-facing flag names and defaults.

Lane Primary Sources Notes
Memory consolidation runtime.py, docs/morpheus/02-runtime-wiring.md Periodic Memlink/living-document consolidation. After the living-document write the driver also fans out to the owner-scoped SAGE reinforcement writer (reinforce_owner_graph_best_effortsage_writer_persist.sage_reinforce_from_store) as a SECOND coexisting, separately-transacted writer of owner-scoped world.relations — INV-022 Surface A rules 4 (per-tx owner GUC via owner_scope) + 5 (two modules/two transactions) preserved; gated on the already-live MEMLINK_HYBRID_SAGE_WRITE_ENABLED, no new flag (SAGE Phase 6, RFC 0097 / ADR 0156).
Troubleshooting probes runtime.py, docs/morpheus/02-runtime-wiring.md Deterministic local probe turns and JSON/Markdown reports. (Distinct from the deleted capability-truth probes — this troubleshooting loop survives.)
Pending Approvals (survives) telegram_approval.py, docs/morpheus/10-telegram-approval.md Operator approval queue for sudo-class actions. The only survivor of the removed Capabilities/architect lane (PR #611).
Self-edit runtime.py, steelmoth-runtime/scripts/morpheus-self-edit-session.py, docs/morpheus/05-self-edit-script.md Bounded subprocess repair session.
Endless dreaming / todo drain endless_dreaming.py, morpheus_drain.py, morpheus_drain_phases.py, morpheus_drain_agents.py, morpheus_drain_state.py, morpheus_plan_artifacts.py Autonomous tagged-todo execution with plan, context, smoke, PR-oriented artifacts, and morpheus/T<id>-<slug> branches. Phase agents (operator directive 2026-07-26): planning defaults to Kimi K3 at max effort with GLM 5.2 fallback, coding to GLM 5.2 at xhigh with Kimi K3 fallback, and the review passes (critic/auditor/plan guardian) ride the planning chain at max — GPT/Claude run only on an explicit staged dashboard pick; an uncredentialed chain blocks the todo with a Telegram note rather than falling back to GPT/Claude.

In private compose, steelmoth-morpheus-init clones the Morpheus workspace from the configured remote and can fall back to a read-only host repo mount at /workspace/steelmoth-host if the remote clone fails. If the remote has no configured base branch and the host mount is a non-Git checkout, init bootstraps a local Git worktree from the host snapshot, excluding runtime cache/run directories, so private boot does not enter a restart loop. That fallback mount is for clone/bootstrap only; it does not change runtime wiki read roots. When the workspace already exists, init best-effort fetches origin and resets only when origin/MORPHEUS_REPO_BASE exists and the checkout is on MORPHEUS_REPO_BASE; active lane branches such as morpheus/* are left intact. After setup, the same service can stay alive as a periodic fetch loop controlled by MORPHEUS_SYNC_INTERVAL_S so the shared workspace refs stay fresh without resetting or cleaning in-flight work. If the remote base ref is still unavailable, the fetch loop reports that state and keeps the local workspace running.

The v2 drain implementation is now split across focused sibling modules. morpheus_drain.py preserves the legacy import surface, stamps the wall-clock breaker, and delegates ordinary todo advancement to _run_drain_cycle_body() in morpheus_drain_phases.py. The sibling modules own branch/dependency helpers, Codex/git/gh subprocess wrappers, prompt builders, DrainState persistence, Telegram question handling, and the Phase 1.5 plan-vs-diff completeness gate. Tests still import the public helpers through steelmoth_runtime.morpheus_drain so existing call sites keep working after the split.

Morpheus defaults are conservative. The docs and config flags show that major autonomous lanes are gated. The todo-drain path adds scope controls through morpheus_scope_guard.py, plan completeness checks, control-loop limits, critic feedback, token and wall-clock budgets, and optional memory recall.

In the v1 endless-dreaming drain lane, endless_dreaming.py now resolves the owner main-chat key and passes it into TodoManager plus list_items() owner filtering, so candidate todo selection stays scoped to the owner-main chat identity.

Bug reports (the /bug + /report chat commands) land in the operator todo ledger with the bug_reports status (migration 0120). Drain candidate selection treats bug_reports as pending-equivalent — both the v1 lane’s pending filter and the v2 lane’s pending/in_progress candidate pull in endless_dreaming.py include it — so an operator-tagged (#morpheus) bug report drains without first leaving the dashboard’s Bug Reports group. The planning and coding prompt builders in morpheus_drain_prompts.py inline a bug report’s attached conversation (the client-approved exchange snapshot on the todo’s attachments JSONB) inside the existing user-supplied delimited block, via bug_reports.render_attachments_for_prompt, which repeats the injection-resistance framing (INV-022 rule 3 pattern): attachment text is evidence, never instructions.

The v2 lane’s per-cycle pick (_select_drain_candidate in endless_dreaming.py) serializes coding to one in-flight todo, then advances a parked (awaiting-plan-approval) plan that needs its approval phase run — operator-approved first (earliest approval wins), else one whose plan was never submitted (the submit lives in the approval phase’s first entry), row-lost (idempotent re-submit), denied (re-plan with feedback), or superseded (block), FIFO — then pre-plans fresh todos while the awaiting backlog has room (morpheus_drain_todos_backlog_cap, default 3), else idles. A submitted, still-undecided plan parks without consuming the cycle. (Fixed 2026-07-03: the original 2026-06-29 backlog scheduler only re-picked approved parked plans, so an unsubmitted plan — e.g. bug report T62 — never reached the operator’s queue and deadlocked, and Deny/supersede decisions were never applied.)

Runtime startup now probes Morpheus launch and drain-state directories before spawning child daemons. The runtime entrypoint tries to repair run-directory ownership and permissions, but exits with a startup error if endless dreaming is enabled and those paths still are not writable by the steelmoth user. That fail-closed rule applies to the API-hosted daemon as well as worker roles.

The API readiness route and private container healthcheck now reuse steelmoth_runtime.morpheus_daemon_health. When endless dreaming is enabled, readiness requires Morpheus run-path writability, daemon process presence, parseable state, positive cycle count, and recent endless-dreaming log activity. The generic liveness route remains a process-only signal. Before filesystem checks, the probe drops to the runtime user (steelmoth) when invoked as container root so Docker healthchecks do not false-fail on user-namespace constrained mounts.

Morpheus and Builder Memory recall also tolerate a mixed legacy/current embedding corpus. Each vector leg filters to the query vector’s dimension before any fixed-dimension cast or cosine distance; Builder Memory’s FTS and path-exact legs still recall incompatible legacy rows. A bounded maintenance CLI, python -m steelmoth_runtime.morpheus_memory_reembed, previews the exact owner-scoped mismatch count without embedding calls or writes by default. Wet runs require the exact owner+dimension token printed by that preview and remain a separate bulk-memory approval.

Sudo-class actions are distinct from normal code edits. They require the Telegram approval service (Pending Approvals — survives PR #611), an allowlist, and audit output before they can run. (The architect remediation dispatcher that used to enqueue these as “L3” tickets was removed in PR #611, 2026-06-22; the approval queue and allowlist executor remain.)

The dashboard Morpheus pages consume runtime routes from web_chat/routes_morpheus.py and autonomous snapshots from routes_autonomous.py. The dashboard surfaces should be treated as operator control panels over runtime state, not as the source of truth for the actual daemon behavior.

  • Update this page when Morpheus flags, runtime startup hooks, approval behavior, drain module boundaries, drain phases, or protected-path validation change.
  • Re-read docs/morpheus/09-config-flags.md and config.py together; flag docs can become stale if config parsing changes.
  • For autonomous edit changes, cite the relevant tests and scope guard source.
  • Current live Morpheus process state is not inferable from repo files; inspect running containers/processes and run artifacts before claiming it is active.