Skip to content

Phase 5 — The Final Purge

Status: 🔨 in progress

Deliverable: Python tool scripts ported to Go or WASM. Python disappears entirely from the runtime path.

Completion lanes: Phase 5 spans Lane 3 — Tool Surface, Security, And Skills, Lane 4 — Gateway, Channels, Cron, And Delivery, and Lane 5 — CLI, API, TUI, Packaging, And Release. The phase is not “port every handler first.” Descriptor, schema, availability, trust, audit, and doctor contracts must land before broad tool or CLI handler ports.

Phase 5 is when Python disappears entirely from the runtime path. Each sub-phase is a separable spec.

SubphaseStatusDeliverable
5.A — Tool Surface Port⏳ plannedKeep the 61-tool registry as inventory only; execute through schema parity, then refresh the Hermes b35d692f manifest for Discord split/cron schema/toolset drift before pure/core tools, stateful groups, and network/browser/sandbox-dependent handlers
5.B — Sandboxing Backends⏳ plannedPort the environment interface and file-sync contract first, then Docker, Modal, Daytona, and Singularity as backend-specific implementations
5.C — Browser Automation⏳ plannedFreeze the browser action/result transcript, then bind Chromedp/Rod and optional Browserbase/Firecrawl provider fallbacks behind the shared contract
5.D — Vision + Image Generation⏳ plannedSplit multimodal work into vision input normalization/token budgeting and image-generation result/storage contracts
5.E — TTS / Voice / Transcription⏳ plannedSplit voice work into voice-mode state, transcription ingestion, TTS synthesis, and gateway media-delivery hooks
5.F — Skills System (Remaining)⏳ plannedPort remaining tools/{skill_manager_tool,skills_hub,skills_sync,skills_guard}.py + registry metadata on top of the Phase 2.G active/inactive store, plus upstream skill preprocessing, skill-backed slash command preprocessing, and bundled-skill credential evidence such as Airtable. Note: Core learning loop (skill extraction, improvement) is Phase 6
5.F.1 — Skills Hub Integration⏳ plannedPort skills.sh, clawhub, lobehub, hermes-index registries
5.F.2 — Skill Auto-Discovery⏳ plannedPort auto-generated skill discovery and metadata management
5.G — MCP Integration✅ completeDependency-ordered MCP slices are validated: config/env resolver, stdio/HTTP discovery, schema normalization, OAuth state/refresh recovery, and managed tool gateway bridge. Honcho MCP HONCHO_API_URL self-hosted drift is handled as server-local MCP config, not a hosted dependency for internal Goncho memory
5.H — ACP Integration⏳ plannedPort acp_adapter/ as an authenticated protocol server with session lifecycle, tool permission prompts, and event streaming tests
5.I — Plugins Architecture⏳ plannedPort plugin manifest loading, capability registration, version checks, isolation boundaries, then extension install/enable/disable flows; upstream Spotify has moved into plugins/spotify/, so it is now the first first-party plugin fixture rather than a built-in tool port
5.J — Approval / Security Guards⏳ plannedPort tools/{approval,path_security,url_safety,tirith_security,website_policy}.py as small guard slices: dangerous-command detection, approval-mode config, cron approvals.cron_mode, then combined Tirith/path/URL/website policy decisions
5.K — Code Execution✅ completeGo-native execute_code now runs guarded shell snippets with timeout/output caps and filesystem/network blocking; Python runtimes are hard-blocked at terminal and execute-code boundaries; broader backend-specific sandboxes remain Phase 5.B
5.L — File Ops + Patches⏳ plannedSplit tools/{file_operations,file_tools,checkpoint_manager,patch_parser}.py into checkpoint shadow-repo GC, file-read dedup/cache guards, then write/patch/rollback primitives
5.M — Mixture of Agents⏳ plannedPort tools/mixture_of_agents_tool.py only after provider routing and subagent envelopes are stable
5.N — Misc Operator Tools⏳ plannedPort todo, clarify, session search, debug helpers, send_message, cronjob tools, and interrupt as small contracts; session search must reuse Phase 3 lineage/source evidence and exclude the current lineage root in recent mode; cron parity remains split into tool API/schedule parsing, context_from output chaining, prompt/script safety, and multi-target/media/live-adapter delivery follow-ups
5.O — Hermes CLI Parity⏳ plannedPort the 49-file hermes_cli/ tree as dependency-aware command groups: deterministic helpers, PTY bridge adapter, registry/active-turn/busy policy, profile path/active-profile helpers before config/auth/setup UI, gormes chat -q scripted-chat model/provider resolution plus removed -z/--oneshot guidance, current auth command-tree parity (auth add/list/remove/reset/status/logout/spotify; top-level login is removed guidance), platform toolset persistence/MCP sentinel behavior, RestartSec-aware service restart polling, gateway management read-model closeout before mutating commands, local log snapshot diagnostics before backup/upload behavior, and later webhook/cron/platform/status command groups; replaces the upstream hermes binary
5.P — Docker / Packaging⏳ plannedMirror upstream Docker/Homebrew/release layout with gormes doctor --offline smoke checks and no Python runtime dependency in the final image; publish Unix install.sh through GitHub Releases, keep Windows install.cmd/install.ps1 as landing-site aliases, and freeze the root/FHS vs user-scoped Unix layout policy from Hermes b35d692f
5.Q — API Server + TUI Gateway Streaming Surface⏳ plannedPort tui_gateway/ plus the upstream OpenAI-compatible gateway/platforms/api_server.py surface: Bubble Tea remote streaming, native TUI/no-Node bundle independence after Hermes ee0728c6, TUI startup model/provider override and static alias behavior from 283c8fd6, native selection/copy parity-or-divergence after edc78e25, /v1/chat/completions, /v1/responses, /v1/runs/{id}/events, incomplete snapshot persistence on disconnect/cancel, gateway proxy mode, dashboard-facing API contracts, /health/detailed, and cron admin endpoints over the native Go runtime
5.R — Code Execution Mode Policy⏳ plannedSplit upstream PR #11971 into four dependency-ordered TDD slices — mode resolver + config precedence, strict-mode CWD/interpreter parity, project-mode CWD + active venv detection, then default-mode selection + config cut-over — without widening the shipped 5.K filesystem/network blocking contract

Phase 5.F (Skills System port) is the mechanical work: porting the upstream Python skills plumbing. Phase 6 (The Learning Loop) is the algorithm on top — detecting complexity, distilling patterns, scoring feedback. Phase 5.F is a dependency of Phase 6, but they are not the same work.

Phase 2.D shipped the Go-native cron MVP: scheduler, job store, run audit, CRON.md mirror, and Heartbeat delivery rules. It did not port the full upstream cron operator surface. The remaining cron/jobs.py, cron/scheduler.py, and tools/cronjob_tools.py parity work belongs in 5.N as TDD slices so it can reuse the Phase 2.D store without reopening the shipped cron audit contract. Hermes b35d692f added context_from chaining; Gormes should map that to the native run audit/output read model rather than copying Hermes’ Markdown output directory as source of truth.

Hermes b35d692f also reshaped the operator tool surface: Discord is now split into discord and discord_admin toolsets with platform restrictions, cronjob schemas include context_from, Feishu gained document/drive toolset coverage, and hermes tools persistence hardens MCP server names, numeric YAML keys, no_mcp, and restricted toolsets. The 5.A manifest-refresh row must land before handler or CLI rows use the old embedded manifest, otherwise workers will keep targeting the stale discord_server shape.

Hermes 4921b269 adds a smaller toolset regression fix: homeassistant stays default-off when HASS_TOKEN is absent, but the env var opts it back into cron/CLI default toolsets because the runtime check function already gates the actual HA tools. Track this as a pure internal/cli/toolset_config.go row; do not combine it with Home Assistant handlers, cron execution, or unrelated default-off toolsets such as MOA/RL.

Hermes 5006b220 adds two CLI/service deltas that Gormes should freeze as small rows before broad CLI ports: top-level one-shot mode (hermes -z) with explicit model/provider/env resolution, and update restart polling that waits through systemd RestartSec before declaring the gateway failed to relaunch. The parser half of one-shot mode is already validated; keep final-output capture, noninteractive safety policy, RestartSec parsing, and active-status polling as separate rows so workers do not mix output plumbing with service-manager state machines.

Current upstream Hermes auth is not auth login: hermes login is a removed shim that points users to hermes auth, hermes model, or hermes setup. The non-deprecated provider command family is auth add/list/remove/reset/status/logout/spotify, with top-level logout kept as a narrow provider-auth shortcut. Gormes should land the command-tree manifest refresh before cmd/gormes/auth.go, then port the credential-pool commands before OAuth provider adapters and the Spotify service-provider subcommand.

The OpenAI-compatible API server is not the Phase 1 bridge. Phase 1 consumes Python’s api_server; Phase 5.Q replaces that donor surface in Go. The latest upstream API server adds stored Responses snapshots for disconnect/cancel paths and gateway proxy mode; keep those as separate slices after the base chat/Responses contracts so client-resilience work does not hide basic HTTP parity failures. Keep cron admin endpoints behind the 5.N cronjob parity slices so HTTP control, CLI control, and tool control all share one scheduler/store contract. Hermes ee0728c6 fixed a first-launch TUI rebuild bug by treating a missing packages/hermes-ink/dist/ink-bundle.js as stale; Gormes should not port that Node/Ink machinery, but it should fixture-lock that native TUI startup, doctor/status output, docs, and landing-page install copy never require npm, HERMES_TUI_DIR, or Hermes bundle files. Hermes 283c8fd6 moved model/provider override state into TUI launch and resolved short aliases without startup network lookup; Gormes should adapt that into the native Cobra/Bubble Tea path instead of leaving overrides oneshot-only. Hermes edc78e25/31d7f195 tightened custom Ink selection copy over SSH, indentation, rendered spaces, and bounds; Gormes’ next slice should explicitly document and fixture-lock terminal-native Bubble Tea selection with no advertised custom copy hotkey. A later Go-native copy mode can be planned separately if the product decision changes. Hermes’ local interactive terminal is not the old Node/Ink bundle: cli.py owns the prompt_toolkit chat surface with bottom-pinned input, skin-aware prompt symbols, response boxes, status bars, busy-input routing, slash autocomplete, modal approval/clarify/secret panels, paste/image handling, and tool-progress scrollback. Exact Gormes TUI parity therefore means replacing the current Bubble Tea dashboard chrome with that operator contract while preserving the Go-native kernel/event boundary.

The retired donor study strengthened the Phase 5 rule: do not start by porting handlers. Start by freezing operation/tool descriptors.

Each ported operation should declare:

  • name and description;
  • JSON schema and result envelope;
  • toolset/category;
  • availability check;
  • mutating or read-only;
  • idempotent or not;
  • prompt-visible or operator-only;
  • allowed trust classes;
  • timeout and result-size budget;
  • audit event kind;
  • degraded-mode status field.

Those descriptors should drive model tool schemas, CLI/gateway command surfaces, doctor checks, audit taxonomy, and fixture generation wherever possible. A Python donor file remains inventory until the descriptor and parity fixture exist.

Hermes adds the schema-repair lesson: dynamic schemas must reflect available tools. If a related tool or provider is disabled, the prompt-visible schema must not advertise an impossible path that causes hallucinated tool calls.

Phase 5 is the highest-risk place to accidentally create giant porting tasks. Treat every broad row above as an inventory bucket, not a direct worker assignment.

  1. Start with schema parity, not handlers. The first 5.A slice should snapshot upstream tool names, toolsets, required env vars, and JSON result shapes so later ports can prove compatibility without reading the Python tree repeatedly.
  2. Land shared contracts before heavy backends. The environment/file-sync interface must precede Docker/Modal/Daytona/Singularity. The browser action transcript must precede Chromedp/Rod/provider bindings. The checkpoint/path-policy contract must precede write-capable file tools.
  3. Keep external-service work fixture-first. Browserbase, Firecrawl, MCP OAuth, ACP, cloud sandboxes, image models, TTS, and transcription should all land with fake clients before any live credential smoke test.
  4. Reuse existing Gormes substrates. Cron tool/API parity should reuse Phase 2.D stores. Session search should reuse Phase 3 catalog and GONCHO scoping. Skills hub and preprocessing work should reuse the Phase 2.G active/inactive store. CLI parity should consume the same gateway/pairing/status read models as the runtime.
  5. 5.R mode policy is strictly additive. The shipped 5.K sandboxed-exec envelope (status, error, filesystem_access, network_access, stdout/stderr caps, timeout) is a public contract. 5.R slices must not widen or renegotiate it — they only choose CWD and interpreter per mode. Land the pure resolver first, then strict parity, then project mode, then the default cut-over; the order matters because both later slices depend on the frozen resolver and the pinned strict baseline.
  6. 5.P installer parity is release-asset-bounded. The Unix installer lives at repo-root install.sh and is published through GitHub Releases, not the custom-domain landing site; Windows installer assets stay under the landing-site module with tests guarding their published copies. The Go install_unix_test.go/install_windows_test.go tests must drive the scripts under fake toolchains — no network calls, no root-owned writes, no Python/Node side-installs — so Gormes stays a single-binary deployment target even as the installer surface widens. Hermes b35d692f changed root Linux installs toward an FHS layout, so the new row must either port that behavior or document and test an intentional user-scoped Gormes divergence before public install copy changes.
  7. 5.Q dashboard drift is API-contract inventory. The upstream React dashboard is not a reason to add Node/TypeScript to the Gormes runtime. Track its chat, session, model picker, OAuth, tool-progress, PTY, and plugin-panel expectations as API contracts first; a Go-native dashboard UI can be decided only after the native endpoints are stable.
  8. 5.O CLI buckets stay split by side effect. gormes chat -q, final-output capture, noninteractive safety, and removed -z/--oneshot guidance are validated on main. Remaining broad CLI buckets must stay dependency-ordered: profile path/active-profile helpers before config/auth/setup commands, gateway read-model closeout before mutating service commands, and local log snapshot capture before backup/archive/upload behavior.
  9. 5.O service restart polling is parser first, poller second. Parse fake RestartUSec output and compute bounded restart delays before landing the fake active-status poller that waits max(10s, RestartSec+10s). Neither row should touch real systemctl, Windows service control, installers, or gateway restart logic.
  10. 5.Q TUI bundle drift is a deliberate divergence. Upstream Hermes still has to defend its Node/Ink TUI bundle, including the ee0728c6 stale-bundle rebuild check. Gormes proves the opposite with cmd/gormes/tui_bundle_independence_test.go: native Bubble Tea startup and offline status do not shell out to npm/node, inspect node_modules, or require packages/hermes-ink/dist/ink-bundle.js.
  11. 5.Q TUI model/copy drift is native-first. Port 283c8fd6 model/provider startup override semantics into Gormes’ Cobra/Bubble Tea path with static alias fixtures and no provider catalog network calls. Treat edc78e25/31d7f195 Ink selection-copy fixes as an explicit divergence row for now: docs and TUI status should say Gormes relies on terminal-native selection and should not advertise custom copy hotkeys until a Go-native copy mode exists.

Before writing a new Phase 5 slice, route through the gormes-references skill (docs/development-skills/gormes-references/SKILL.md) to find the donor file that already shapes the seam.

Phase 5 problemDonor fileNotes
5.A tool registry + descriptor-driven schema/availability/trustnanobot/pkg/tools/service.go, nanobot/pkg/tools/flows.goApache 2.0; descriptor pattern
5.A tool-output truncation while persisting full bytes (artifact pointer)nanobot/pkg/agents/truncate.goAlready used in Phase 2 inbound
5.A image-token estimation per providernanobot/pkg/agents/tokencount.goConservative per-provider fallback
5.B sandbox environment interface + cancellable workersnanobot/pkg/runtime/runtime.goExplicit dependency layering
5.G MCP serialized write queue (deterministic, cancel-before-start)engram/internal/mcp/write_queue.goAlready in production use in engram
5.G MCP activity/audit logging (redaction, append-only)engram/internal/mcp/activity.goSame audit shape Gormes uses in 2.D/3.E
5.J approval / dangerous-action filters with declarative pre-call gatesnanobot/pkg/tools/flows.go, axe/internal/tool/Filter helpers + flow gates
5.J path-traversal/URL/website policy guardsaxe/internal/artifact/tracker.goSanitized-path pattern, append-only registry
5.K code execution sandbox + bounded stdout/stderr capsnanobot/pkg/agents/truncate.goOutput-cap policy already shipped uses this shape
5.L file-ops checkpoint + path-sanitization + dedupaxe/internal/artifact/tracker.goPath-traversal guard for write-capable file tools
5.M mixture-of-agents — workflow agents (loop / sequential / parallel)adk-go/agent/workflowagents/...Workflow primitives without rewriting kernel
5.N session-search / debug helpers — bounded token budgetaxe/internal/budget/budget.goPer-turn counter + reset
5.O CLI parity — config/profile/dotenv layered loadersaxe/internal/config/, axe/internal/xdg/XDG-respecting layered config
5.O CLI parity — credential/auth surfacegoclaw/internal/oauth/openai.go, goclaw/internal/oauth/token.goCode permitted with provenance for PKCE/state/token-source shape; Hermes hermes_cli/auth.py and hermes_cli/auth_commands.py remain the behavior contract
5.Q API server proxy mode + run-event SSEnanobot/pkg/runtime/runtime.goCancellable session-scoped workers
5.R code-execution-mode resolver (strict vs project, CWD/interpreter)axe/internal/resolve/, axe/internal/envinterp/Per-mode resolver pattern

Provider-side surfaces (auth/streaming/quota/retry) inside any 5.x tool route through gormes-provider-parity and references/go-agent-os/GORMES-PROVIDER-PATTERN-REFERENCES.md instead of re-deriving the OAuth/quota classifier.