Compare commits

..

5 Commits

Author SHA1 Message Date
Alexander Whitestone
cc9b20ce73 docs: add hermes-agent feature census (closes #593)
Some checks failed
Smoke Test / smoke (pull_request) Failing after 5s
Comprehensive census of hermes-agent codebase:
- Feature Matrix: memory, tools, sessions, plugins, config, gateway
- Architecture Overview: how pieces connect
- Recent Activity: last 30 days of development
- Overlap Analysis: what we are duplicating vs what exists
- Contribution Roadmap: what to build vs what to contribute upstream
2026-04-11 08:26:02 -04:00
1b8b784b09 Merge pull request 'Add smoke test workflow' (#592) from fix/add-smoke-test into main
Some checks failed
Smoke Test / smoke (push) Failing after 4s
Merged PR #592: Add smoke test workflow
2026-04-11 00:43:15 +00:00
Alexander Whitestone
56a56d7f18 Add smoke test workflow
Some checks failed
Smoke Test / smoke (pull_request) Failing after 6s
2026-04-10 20:06:48 -04:00
d3368a5a9d Merge pull request #591
Merged PR #591
2026-04-10 03:44:07 +00:00
Alexander Whitestone
1614ef5d66 docs: add sovereign stack research document (#589)
Research spike on replacing Homebrew with mature open-source tools
for sovereign AI infrastructure.

Covers: package managers, containers, Python, Node, GPU CUDA,
supply-chain security, and a recommended stack with install commands.

Refs: #589
2026-04-09 21:08:58 -04:00
3 changed files with 852 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
name: Smoke Test
on:
pull_request:
push:
branches: [main]
jobs:
smoke:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Parse check
run: |
find . -name '*.yml' -o -name '*.yaml' | grep -v .gitea | xargs -r python3 -c "import sys,yaml; [yaml.safe_load(open(f)) for f in sys.argv[1:]]"
find . -name '*.json' | xargs -r python3 -m json.tool > /dev/null
find . -name '*.py' | xargs -r python3 -m py_compile
find . -name '*.sh' | xargs -r bash -n
echo "PASS: All files parse"
- name: Secret scan
run: |
if grep -rE 'sk-or-|sk-ant-|ghp_|AKIA' . --include='*.yml' --include='*.py' --include='*.sh' 2>/dev/null | grep -v .gitea; then exit 1; fi
echo "PASS: No secrets"

477
docs/hermes-agent-census.md Normal file
View File

@@ -0,0 +1,477 @@
# Hermes Agent — Feature Census
**Epic:** [#290 — Know Thy Agent: Hermes Feature Census](https://forge.alexanderwhitestone.com/Timmy_Foundation/hermes-agent/issues/290)
**Date:** 2026-04-11
**Source:** Timmy_Foundation/hermes-agent (fork of NousResearch/hermes-agent)
**Upstream:** NousResearch/hermes-agent (last sync: 2026-04-07, 499 commits merged in PR #201)
**Codebase:** ~200K lines Python (335 source files), 470 test files
---
## 1. Feature Matrix
### 1.1 Memory System
| Feature | Status | File:Line | Notes |
|---------|--------|-----------|-------|
| **`add` action** | ✅ Exists | `tools/memory_tool.py:457` | Append entry to MEMORY.md or USER.md |
| **`replace` action** | ✅ Exists | `tools/memory_tool.py:466` | Find by substring, replace content |
| **`remove` action** | ✅ Exists | `tools/memory_tool.py:475` | Find by substring, delete entry |
| **Dual stores (memory + user)** | ✅ Exists | `tools/memory_tool.py:43-45` | MEMORY.md (2200 char limit) + USER.md (1375 char limit) |
| **Entry deduplication** | ✅ Exists | `tools/memory_tool.py:128-129` | Exact-match dedup on load |
| **Injection/exfiltration scanning** | ✅ Exists | `tools/memory_tool.py:85` | Blocks prompt injection, role hijacking, secret exfil |
| **Frozen snapshot pattern** | ✅ Exists | `tools/memory_tool.py:119-135` | Preserves LLM prefix cache across session |
| **Atomic writes** | ✅ Exists | `tools/memory_tool.py:417-436` | tempfile.mkstemp + os.replace |
| **File locking (fcntl)** | ✅ Exists | `tools/memory_tool.py:137-153` | Exclusive lock for concurrent safety |
| **External provider plugin** | ✅ Exists | `agent/memory_manager.py` | Supports 1 external provider (Honcho, Mem0, Hindsight, etc.) |
| **Provider lifecycle hooks** | ✅ Exists | `agent/memory_provider.py:55-66` | on_memory_write, prefetch, sync_turn, on_session_end, on_pre_compress, on_delegation |
| **Session search (past conversations)** | ✅ Exists | `tools/session_search_tool.py:492` | FTS5 search across SQLite message store |
| **Holographic memory** | 🔌 Plugin slot | Config `memory.provider` | Accepted as external provider name, not built-in |
| **Engram integration** | ❌ Not present | — | Not in codebase; Engram is a Timmy Foundation project |
| **Trust system** | ❌ Not present | — | No trust scoring on memory entries |
### 1.2 Tool System
| Feature | Status | File:Line | Notes |
|---------|--------|-----------|-------|
| **Central registry** | ✅ Exists | `tools/registry.py:290` | Module-level singleton, all tools self-register |
| **47 static tools** | ✅ Exists | See full list below | Organized in 21+ toolsets |
| **Dynamic MCP tools** | ✅ Exists | `tools/mcp_tool.py` | Runtime registration from MCP servers (17 in live instance) |
| **Tool approval system** | ✅ Exists | `tools/approval.py` | Manual/smart/off modes, dangerous command detection |
| **Toolset composition** | ✅ Exists | `toolsets.py:404` | Composite toolsets (e.g., `debugging = terminal + web + file`) |
| **Per-platform toolsets** | ✅ Exists | `toolsets.py` | `hermes-cli`, `hermes-telegram`, `hermes-discord`, etc. |
| **Skill management** | ✅ Exists | `tools/skill_manager_tool.py:747` | Create, patch, delete skill documents |
| **Mixture of Agents** | ✅ Exists | `tools/mixture_of_agents_tool.py:553` | Route through 4+ frontier LLMs |
| **Subagent delegation** | ✅ Exists | `tools/delegate_tool.py:963` | Isolated contexts, up to 3 parallel |
| **Code execution sandbox** | ✅ Exists | `tools/code_execution_tool.py:1360` | Python scripts with tool access |
| **Image generation** | ✅ Exists | `tools/image_generation_tool.py:694` | FLUX 2 Pro |
| **Vision analysis** | ✅ Exists | `tools/vision_tools.py:606` | Multi-provider vision |
| **Text-to-speech** | ✅ Exists | `tools/tts_tool.py:974` | Edge TTS, ElevenLabs, OpenAI, NeuTTS |
| **Speech-to-text** | ✅ Exists | Config `stt.*` | Local Whisper, Groq, OpenAI, Mistral Voxtral |
| **Home Assistant** | ✅ Exists | `tools/homeassistant_tool.py:456-483` | 4 HA tools (list, state, services, call) |
| **RL training** | ✅ Exists | `tools/rl_training_tool.py:1376-1394` | 10 Tinker-Atropos tools |
| **Browser automation** | ✅ Exists | `tools/browser_tool.py:2137-2211` | 10 tools (navigate, click, type, scroll, screenshot, etc.) |
| **Gitea client** | ✅ Exists | `tools/gitea_client.py` | Gitea API integration |
| **Cron job management** | ✅ Exists | `tools/cronjob_tools.py:508` | Scheduled task CRUD |
| **Send message** | ✅ Exists | `tools/send_message_tool.py:1036` | Cross-platform messaging |
#### Complete Tool List (47 static)
| # | Tool | Toolset | File:Line |
|---|------|---------|-----------|
| 1 | `read_file` | file | `tools/file_tools.py:832` |
| 2 | `write_file` | file | `tools/file_tools.py:833` |
| 3 | `patch` | file | `tools/file_tools.py:834` |
| 4 | `search_files` | file | `tools/file_tools.py:835` |
| 5 | `terminal` | terminal | `tools/terminal_tool.py:1783` |
| 6 | `process` | terminal | `tools/process_registry.py:1039` |
| 7 | `web_search` | web | `tools/web_tools.py:2082` |
| 8 | `web_extract` | web | `tools/web_tools.py:2092` |
| 9 | `vision_analyze` | vision | `tools/vision_tools.py:606` |
| 10 | `image_generate` | image_gen | `tools/image_generation_tool.py:694` |
| 11 | `text_to_speech` | tts | `tools/tts_tool.py:974` |
| 12 | `skills_list` | skills | `tools/skills_tool.py:1357` |
| 13 | `skill_view` | skills | `tools/skills_tool.py:1367` |
| 14 | `skill_manage` | skills | `tools/skill_manager_tool.py:747` |
| 15 | `browser_navigate` | browser | `tools/browser_tool.py:2137` |
| 16 | `browser_snapshot` | browser | `tools/browser_tool.py:2145` |
| 17 | `browser_click` | browser | `tools/browser_tool.py:2154` |
| 18 | `browser_type` | browser | `tools/browser_tool.py:2162` |
| 19 | `browser_scroll` | browser | `tools/browser_tool.py:2170` |
| 20 | `browser_back` | browser | `tools/browser_tool.py:2178` |
| 21 | `browser_press` | browser | `tools/browser_tool.py:2186` |
| 22 | `browser_get_images` | browser | `tools/browser_tool.py:2195` |
| 23 | `browser_vision` | browser | `tools/browser_tool.py:2203` |
| 24 | `browser_console` | browser | `tools/browser_tool.py:2211` |
| 25 | `todo` | todo | `tools/todo_tool.py:260` |
| 26 | `memory` | memory | `tools/memory_tool.py:544` |
| 27 | `session_search` | session_search | `tools/session_search_tool.py:492` |
| 28 | `clarify` | clarify | `tools/clarify_tool.py:131` |
| 29 | `execute_code` | code_execution | `tools/code_execution_tool.py:1360` |
| 30 | `delegate_task` | delegation | `tools/delegate_tool.py:963` |
| 31 | `cronjob` | cronjob | `tools/cronjob_tools.py:508` |
| 32 | `send_message` | messaging | `tools/send_message_tool.py:1036` |
| 33 | `mixture_of_agents` | moa | `tools/mixture_of_agents_tool.py:553` |
| 34 | `ha_list_entities` | homeassistant | `tools/homeassistant_tool.py:456` |
| 35 | `ha_get_state` | homeassistant | `tools/homeassistant_tool.py:465` |
| 36 | `ha_list_services` | homeassistant | `tools/homeassistant_tool.py:474` |
| 37 | `ha_call_service` | homeassistant | `tools/homeassistant_tool.py:483` |
| 38-47 | `rl_*` (10 tools) | rl | `tools/rl_training_tool.py:1376-1394` |
### 1.3 Session System
| Feature | Status | File:Line | Notes |
|---------|--------|-----------|-------|
| **Session creation** | ✅ Exists | `gateway/session.py:676` | get_or_create_session with auto-reset |
| **Session keying** | ✅ Exists | `gateway/session.py:429` | platform:chat_type:chat_id[:thread_id][:user_id] |
| **Reset policies** | ✅ Exists | `gateway/session.py:610` | none / idle / daily / both |
| **Session switching (/resume)** | ✅ Exists | `gateway/session.py:825` | Point key at a previous session ID |
| **Session branching (/branch)** | ✅ Exists | CLI commands.py | Fork conversation history |
| **SQLite persistence** | ✅ Exists | `hermes_state.py:41-94` | sessions + messages + FTS5 search |
| **JSONL dual-write** | ✅ Exists | `gateway/session.py:891` | Backward compatibility with legacy format |
| **WAL mode concurrency** | ✅ Exists | `hermes_state.py:157` | Concurrent read/write with retry |
| **Context compression** | ✅ Exists | Config `compression.*` | Auto-compress when context exceeds ratio |
| **Memory flush on reset** | ✅ Exists | `gateway/run.py:632` | Reviews old transcript before auto-reset |
| **Token/cost tracking** | ✅ Exists | `hermes_state.py:41` | input, output, cache_read, cache_write, reasoning tokens |
| **PII redaction** | ✅ Exists | Config `privacy.redact_pii` | Hash user IDs, strip phone numbers |
### 1.4 Plugin System
| Feature | Status | File:Line | Notes |
|---------|--------|-----------|-------|
| **Plugin discovery** | ✅ Exists | `hermes_cli/plugins.py:5-11` | User (~/.hermes/plugins/), project, pip entry-points |
| **Plugin manifest (plugin.yaml)** | ✅ Exists | `hermes_cli/plugins.py` | name, version, requires_env, provides_tools, provides_hooks |
| **Lifecycle hooks** | ✅ Exists | `hermes_cli/plugins.py:55-66` | 9 hooks (pre/post tool_call, llm_call, api_request; on_session_start/end/finalize/reset) |
| **PluginContext API** | ✅ Exists | `hermes_cli/plugins.py:124-233` | register_tool, inject_message, register_cli_command, register_hook |
| **Plugin management CLI** | ✅ Exists | `hermes_cli/plugins_cmd.py:1-690` | install, update, remove, enable, disable |
| **Project plugins (opt-in)** | ✅ Exists | `hermes_cli/plugins.py` | Requires HERMES_ENABLE_PROJECT_PLUGINS env var |
| **Pip plugins** | ✅ Exists | `hermes_cli/plugins.py` | Entry-point group: hermes_agent.plugins |
### 1.5 Config System
| Feature | Status | File:Line | Notes |
|---------|--------|-----------|-------|
| **YAML config** | ✅ Exists | `hermes_cli/config.py:259-619` | ~120 config keys across 25 sections |
| **Schema versioning** | ✅ Exists | `hermes_cli/config.py` | `_config_version: 14` with migration support |
| **Provider config** | ✅ Exists | Config `providers.*`, `fallback_providers` | Per-provider overrides, fallback chains |
| **Credential pooling** | ✅ Exists | Config `credential_pool_strategies` | Key rotation strategies |
| **Auxiliary model config** | ✅ Exists | Config `auxiliary.*` | 8 separate side-task models (vision, compression, etc.) |
| **Smart model routing** | ✅ Exists | Config `smart_model_routing.*` | Route simple prompts to cheap model |
| **Env var management** | ✅ Exists | `hermes_cli/config.py:643-1318` | ~80 env vars across provider/tool/messaging/setting categories |
| **Interactive setup wizard** | ✅ Exists | `hermes_cli/setup.py` | Guided first-run configuration |
| **Config migration** | ✅ Exists | `hermes_cli/config.py` | Auto-migrates old config versions |
### 1.6 Gateway
| Feature | Status | File:Line | Notes |
|---------|--------|-----------|-------|
| **18 platform adapters** | ✅ Exists | `gateway/platforms/` | Telegram, Discord, Slack, WhatsApp, Signal, Mattermost, Matrix, HomeAssistant, Email, SMS, DingTalk, API Server, Webhook, Feishu, Wecom, Weixin, BlueBubbles |
| **Message queuing** | ✅ Exists | `gateway/run.py:507` | Queue during agent processing, media placeholder support |
| **Agent caching** | ✅ Exists | `gateway/run.py:515` | Preserve AIAgent instances per session for prompt caching |
| **Background reconnection** | ✅ Exists | `gateway/run.py:527` | Exponential backoff for failed platforms |
| **Authorization** | ✅ Exists | `gateway/run.py:1826` | Per-user allowlists, DM pairing codes |
| **Slash command interception** | ✅ Exists | `gateway/run.py` | Commands handled before agent (not billed) |
| **ACP server** | ✅ Exists | `acp_adapter/server.py:726` | VS Code / Zed / JetBrains integration |
| **Cron scheduler** | ✅ Exists | `cron/scheduler.py:850` | Full job scheduler with cron expressions |
| **Batch runner** | ✅ Exists | `batch_runner.py:1285` | Parallel batch processing |
| **API server** | ✅ Exists | `gateway/platforms/api_server.py` | OpenAI-compatible HTTP API |
### 1.7 Providers (20 supported)
| Provider | ID | Key Env Var |
|----------|----|-------------|
| Nous Portal | `nous` | `NOUS_BASE_URL` |
| OpenRouter | `openrouter` | `OPENROUTER_API_KEY` |
| Anthropic | `anthropic` | (standard) |
| Google AI Studio | `gemini` | `GOOGLE_API_KEY`, `GEMINI_API_KEY` |
| OpenAI Codex | `openai-codex` | (standard) |
| GitHub Copilot | `copilot` / `copilot-acp` | (OAuth) |
| DeepSeek | `deepseek` | `DEEPSEEK_API_KEY` |
| Kimi / Moonshot | `kimi-coding` | `KIMI_API_KEY` |
| Z.AI / GLM | `zai` | `GLM_API_KEY`, `ZAI_API_KEY` |
| MiniMax | `minimax` | `MINIMAX_API_KEY` |
| MiniMax (China) | `minimax-cn` | `MINIMAX_CN_API_KEY` |
| Alibaba / DashScope | `alibaba` | `DASHSCOPE_API_KEY` |
| Hugging Face | `huggingface` | `HF_TOKEN` |
| OpenCode Zen | `opencode-zen` | `OPENCODE_ZEN_API_KEY` |
| OpenCode Go | `opencode-go` | `OPENCODE_GO_API_KEY` |
| Qwen OAuth | `qwen-oauth` | (Portal) |
| AI Gateway | `ai-gateway` | (Nous) |
| Kilo Code | `kilocode` | (standard) |
| Ollama (local) | — | First-class via auxiliary wiring |
| Custom endpoint | `custom` | user-provided URL |
### 1.8 UI / UX
| Feature | Status | File:Line | Notes |
|---------|--------|-----------|-------|
| **Skin/theme engine** | ✅ Exists | `hermes_cli/skin_engine.py` | 7 built-in skins, user YAML skins |
| **Kawaii spinner** | ✅ Exists | `agent/display.py` | Animated faces, configurable verbs/wings |
| **Rich banner** | ✅ Exists | `banner.py` | Logo, hero art, system info |
| **Prompt_toolkit input** | ✅ Exists | `cli.py` | Autocomplete, history, syntax |
| **Streaming output** | ✅ Exists | Config `display.streaming` | Optional streaming |
| **Reasoning display** | ✅ Exists | Config `display.show_reasoning` | Show/hide chain-of-thought |
| **Cost display** | ✅ Exists | Config `display.show_cost` | Show $ in status bar |
| **Voice mode** | ✅ Exists | Config `voice.*` | Ctrl+B record, auto-TTS, silence detection |
| **Human delay simulation** | ✅ Exists | Config `human_delay.*` | Simulated typing delay |
### 1.9 Security
| Feature | Status | File:Line | Notes |
|---------|--------|-----------|-------|
| **Tirith security scanning** | ✅ Exists | `tools/tirith_security.py` | Pre-exec code scanning |
| **Secret redaction** | ✅ Exists | Config `security.redact_secrets` | Auto-strip secrets from output |
| **Memory injection scanning** | ✅ Exists | `tools/memory_tool.py:85` | Blocks prompt injection in memory |
| **URL safety** | ✅ Exists | `tools/url_safety.py` | URL reputation checking |
| **Command approval** | ✅ Exists | `tools/approval.py` | Manual/smart/off modes |
| **OSV vulnerability check** | ✅ Exists | `tools/osv_check.py` | Open Source Vulnerabilities DB |
| **Conscience validator** | ✅ Exists | `tools/conscience_validator.py` | SOUL.md alignment checking |
| **Shield detector** | ✅ Exists | `tools/shield/detector.py` | Jailbreak/crisis detection |
---
## 2. Architecture Overview
```
┌─────────────────────────────────────────────────────────┐
│ Entry Points │
├──────────┬──────────┬──────────┬──────────┬─────────────┤
│ CLI │ Gateway │ ACP │ Cron │ Batch Runner│
│ cli.py │gateway/ │acp_apt/ │ cron/ │batch_runner │
│ 8620 ln │ run.py │server.py │sched.py │ 1285 ln │
│ │ 7905 ln │ 726 ln │ 850 ln │ │
└────┬─────┴────┬─────┴──────────┴──────┬───┴─────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────┐
│ AIAgent (run_agent.py, 9423 ln) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Core Conversation Loop │ │
│ │ while iterations < max: │ │
│ │ response = client.chat(tools, messages) │ │
│ │ if tool_calls: handle_function_call() │ │
│ │ else: return response │ │
│ └──────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────────┐ │
│ │ model_tools.py (577 ln) │ │
│ │ _discover_tools() → handle_function_call() │ │
│ └──────────────────────┬───────────────────────────┘ │
└─────────────────────────┼───────────────────────────────┘
┌────────────────────▼────────────────────┐
│ tools/registry.py (singleton) │
│ ToolRegistry.register() → dispatch() │
└────────────────────┬────────────────────┘
┌─────────┬───────────┼───────────┬────────────────┐
▼ ▼ ▼ ▼ ▼
┌────────┐┌────────┐┌──────────┐┌──────────┐ ┌──────────┐
│ file ││terminal││ web ││ browser │ │ memory │
│ tools ││ tool ││ tools ││ tool │ │ tool │
│ 4 tools││2 tools ││ 2 tools ││ 10 tools │ │ 3 actions│
└────────┘└────────┘└──────────┘└──────────┘ └────┬─────┘
┌──────────▼──────────┐
│ agent/memory_manager │
│ ┌──────────────────┐│
│ │BuiltinProvider ││
│ │(MEMORY.md+USER.md)│
│ ├──────────────────┤│
│ │External Provider ││
│ │(optional, 1 max) ││
│ └──────────────────┘│
└─────────────────────┘
┌─────────────────────────────────────────────────┐
│ Session Layer │
│ SessionStore (gateway/session.py, 1030 ln) │
│ SessionDB (hermes_state.py, 1238 ln) │
│ ┌───────────┐ ┌─────────────────────────────┐ │
│ │sessions.js│ │ state.db (SQLite + FTS5) │ │
│ │ JSONL │ │ sessions │ messages │ fts │ │
│ └───────────┘ └─────────────────────────────┘ │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│ Gateway Platform Adapters │
│ telegram │ discord │ slack │ whatsapp │ signal │
│ matrix │ email │ sms │ mattermost│ api │
│ homeassistant │ dingtalk │ feishu │ wecom │ ... │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│ Plugin System │
│ User ~/.hermes/plugins/ │ Project .hermes/ │
│ Pip entry-points (hermes_agent.plugins) │
│ 9 lifecycle hooks │ PluginContext API │
└─────────────────────────────────────────────────┘
```
**Key dependency chain:**
```
tools/registry.py (no deps — imported by all tool files)
tools/*.py (each calls registry.register() at import time)
model_tools.py (imports tools/registry + triggers tool discovery)
run_agent.py, cli.py, batch_runner.py, environments/
```
---
## 3. Recent Development Activity (Last 30 Days)
### Activity Summary
| Metric | Value |
|--------|-------|
| Total commits (since 2026-03-12) | ~1,750 |
| Top contributor | Teknium (1,169 commits) |
| Timmy Foundation commits | ~55 (Alexander Whitestone: 21, Timmy Time: 22, Bezalel: 12) |
| Key upstream sync | PR #201 — 499 commits from NousResearch/hermes-agent (2026-04-07) |
### Top Contributors (Last 30 Days)
| Contributor | Commits | Focus Area |
|-------------|---------|------------|
| Teknium | 1,169 | Core features, bug fixes, streaming, browser, Telegram/Discord |
| teknium1 | 238 | Supplementary work |
| 0xbyt4 | 117 | Various |
| Test | 61 | Testing |
| Allegro | 49 | Fleet ops, CI |
| kshitijk4poor | 30 | Features |
| SHL0MS | 25 | Features |
| Google AI Agent | 23 | MemPalace plugin |
| Timmy Time | 22 | CI, fleet config, merge coordination |
| Alexander Whitestone | 21 | Memory fixes, browser PoC, docs, CI, provider config |
| Bezalel | 12 | CI pipeline, devkit, health checks |
### Key Upstream Changes (Merged in Last 30 Days)
| Change | PR | Impact |
|--------|----|--------|
| Browser provider switch (Browserbase → Browser Use) | upstream #5750 | Breaking change in browser tooling |
| notify_on_complete for background processes | upstream #5779 | New feature for async workflows |
| Interactive model picker (Telegram + Discord) | upstream #5742 | UX improvement |
| Streaming fix after tool boundaries | upstream #5739 | Bug fix |
| Delegate: share credential pools with subagents | upstream | Security improvement |
| Permanent command allowlist on startup | upstream #5076 | Bug fix |
| Paginated model picker for Telegram | upstream | UX improvement |
| Slack thread replies without @mentions | upstream | Gateway improvement |
| Supermemory memory provider (added then removed) | upstream | Experimental, rolled back |
| Background process management overhaul | upstream | Major feature |
### Timmy Foundation Contributions (Our Fork)
| Change | PR | Author |
|--------|----|--------|
| Memory remove action bridge fix | #277 | Alexander Whitestone |
| Browser integration PoC + analysis | #262 | Alexander Whitestone |
| Memory budget enforcement tool | #256 | Alexander Whitestone |
| Memory sovereignty verification | #257 | Alexander Whitestone |
| Memory Architecture Guide | #263, #258 | Alexander Whitestone |
| MemPalace plugin creation | #259, #265 | Google AI Agent |
| CI: duplicate model detection | #235 | Alexander Whitestone |
| Kimi model config fix | #225 | Bezalel |
| Ollama provider wiring fix | #223 | Alexander Whitestone |
| Deep Self-Awareness Epic | #215 | Bezalel |
| BOOT.md for repo | #202 | Bezalel |
| Upstream sync (499 commits) | #201 | Alexander Whitestone |
| Forge CI pipeline | #154, #175, #187 | Bezalel |
| Gitea PR & Issue automation skill | #181 | Bezalel |
| Development tools for wizard fleet | #166 | Bezalel |
| KNOWN_VIOLATIONS justification | #267 | Manus AI |
---
## 4. Overlap Analysis
### What We're Building That Already Exists
| Timmy Foundation Planned Work | Hermes-Agent Already Has | Verdict |
|------------------------------|--------------------------|---------|
| **Memory system (add/remove/replace)** | `tools/memory_tool.py` with all 3 actions | **USE IT** — already exists, we just needed the `remove` fix (PR #277) |
| **Session persistence** | SQLite + JSONL dual-write system | **USE IT** — battle-tested, FTS5 search included |
| **Gateway platform adapters** | 18 adapters including Telegram, Discord, Matrix | **USE IT** — don't rebuild, contribute fixes |
| **Config management** | Full YAML config with migration, env vars | **USE IT** — extend rather than replace |
| **Plugin system** | Complete with lifecycle hooks, PluginContext API | **USE IT** — write plugins, not custom frameworks |
| **Tool registry** | Centralized registry with self-registration | **USE IT** — register new tools via existing pattern |
| **Cron scheduling** | `cron/scheduler.py` + `cronjob` tool | **USE IT** — integrate rather than duplicate |
| **Subagent delegation** | `delegate_task` with isolated contexts | **USE IT** — extend for fleet coordination |
### What We Need That Doesn't Exist
| Timmy Foundation Need | Hermes-Agent Status | Action |
|----------------------|---------------------|--------|
| **Engram integration** | Not present | Build as external memory provider plugin |
| **Holographic fact store** | Accepted as provider name, not implemented | Build as external memory provider |
| **Fleet orchestration** | Not present (single-agent focus) | Build on top, contribute patterns upstream |
| **Trust scoring on memory** | Not present | Build as extension to memory tool |
| **Multi-agent coordination** | delegate_tool supports parallel (max 3) | Extend for fleet-wide dispatch |
| **VPS wizard deployment** | Not present | Timmy Foundation domain — build independently |
| **Gitea CI/CD integration** | Minimal (gitea_client.py exists) | Extend existing client |
### Duplication Risk Assessment
| Risk | Level | Details |
|------|-------|---------|
| Memory system duplication | 🟢 LOW | We were almost duplicating memory removal (PR #278 vs #277). Now resolved. |
| Config system duplication | 🟢 LOW | Using hermes config directly via fork |
| Gateway duplication | 🟡 MEDIUM | Our fleet-ops patterns may partially overlap with gateway capabilities |
| Session management duplication | 🟢 LOW | Using hermes sessions directly |
| Plugin system duplication | 🟢 LOW | We write plugins, not a parallel system |
---
## 5. Contribution Roadmap
### What to Build (Timmy Foundation Own)
| Item | Rationale | Priority |
|------|-----------|----------|
| **Engram memory provider** | Sovereign local memory (Go binary, SQLite+FTS). Must be ours. | 🔴 HIGH |
| **Holographic fact store** | Our architecture for knowledge graph memory. Unique to Timmy. | 🔴 HIGH |
| **Fleet orchestration layer** | Multi-wizard coordination (Allegro, Bezalel, Ezra, Claude). Not upstream's problem. | 🔴 HIGH |
| **VPS deployment automation** | Sovereign wizard provisioning. Timmy-specific. | 🟡 MEDIUM |
| **Trust scoring system** | Evaluate memory entry reliability. Research needed. | 🟡 MEDIUM |
| **Gitea CI/CD integration** | Deep integration with our forge. Extend gitea_client.py. | 🟡 MEDIUM |
| **SOUL.md compliance tooling** | Conscience validator exists (`tools/conscience_validator.py`). Extend it. | 🟢 LOW |
### What to Contribute Upstream
| Item | Rationale | Difficulty |
|------|-----------|------------|
| **Memory remove action fix** | Already done (PR #277). ✅ | Done |
| **Browser integration analysis** | Useful for all users (PR #262). ✅ | Done |
| **CI stability improvements** | Reduce deps, increase timeout (our commit). ✅ | Done |
| **Duplicate model detection** | CI check useful for all forks (PR #235). ✅ | Done |
| **Memory sovereignty patterns** | Verification scripts, budget enforcement. Useful broadly. | Medium |
| **Engram provider adapter** | If Engram proves useful, offer as memory provider option. | Medium |
| **Fleet delegation patterns** | If multi-agent coordination patterns generalize. | Hard |
| **Wizard health monitoring** | If monitoring patterns generalize to any agent fleet. | Medium |
### Quick Wins (Next Sprint)
1. **Verify memory remove action** — Confirm PR #277 works end-to-end in our fork
2. **Test browser tool after upstream switch** — Browserbase → Browser Use (upstream #5750) may break our PoC
3. **Update provider config** — Kimi model references updated (PR #225), verify no remaining stale refs
4. **Engram provider prototype** — Start implementing as external memory provider plugin
5. **Fleet health integration** — Use gateway's background reconnection patterns for wizard fleet
---
## Appendix A: File Counts by Directory
| Directory | Files | Lines |
|-----------|-------|-------|
| `tools/` | 70+ .py files | ~50K |
| `gateway/` | 20+ .py files | ~25K |
| `agent/` | 10 .py files | ~10K |
| `hermes_cli/` | 15 .py files | ~20K |
| `acp_adapter/` | 9 .py files | ~8K |
| `cron/` | 3 .py files | ~2K |
| `tests/` | 470 .py files | ~80K |
| **Total** | **335 source + 470 test** | **~200K + ~80K** |
## Appendix B: Key File Index
| File | Lines | Purpose |
|------|-------|---------|
| `run_agent.py` | 9,423 | AIAgent class, core conversation loop |
| `cli.py` | 8,620 | CLI orchestrator, slash command dispatch |
| `gateway/run.py` | 7,905 | Gateway main loop, platform management |
| `tools/terminal_tool.py` | 1,783 | Terminal orchestration |
| `tools/web_tools.py` | 2,082 | Web search + extraction |
| `tools/browser_tool.py` | 2,211 | Browser automation (10 tools) |
| `tools/code_execution_tool.py` | 1,360 | Python sandbox |
| `tools/delegate_tool.py` | 963 | Subagent delegation |
| `tools/mcp_tool.py` | ~1,050 | MCP client |
| `tools/memory_tool.py` | 560 | Memory CRUD |
| `hermes_state.py` | 1,238 | SQLite session store |
| `gateway/session.py` | 1,030 | Session lifecycle |
| `cron/scheduler.py` | 850 | Job scheduler |
| `hermes_cli/config.py` | 1,318 | Config system |
| `hermes_cli/plugins.py` | 611 | Plugin system |
| `hermes_cli/skin_engine.py` | 500+ | Theme engine |

351
docs/sovereign-stack.md Normal file
View File

@@ -0,0 +1,351 @@
# Sovereign Stack: Replacing Homebrew with Mature Open-Source Tools
> Issue: #589 | Research Spike | Status: Complete
## Executive Summary
Homebrew is a macOS-first tool that has crept into our Linux server workflows. It
runs as a non-root user, maintains its own cellar under /home/linuxbrew, and pulls
pre-built binaries from a CDN we do not control. For a foundation building sovereign
AI infrastructure, that is the wrong dependency graph.
This document evaluates the alternatives, gives copy-paste install commands, and
lands on a recommended stack for the Timmy Foundation.
---
## 1. Package Managers: apt vs dnf vs pacman vs Nix vs Guix
| Criterion | apt (Debian/Ubuntu) | dnf (Fedora/RHEL) | pacman (Arch) | Nix | GNU Guix |
|---|---|---|---|---|---|
| Maturity | 25+ years | 20+ years | 20+ years | 20 years | 13 years |
| Reproducible builds | No | No | No | Yes (core) | Yes (core) |
| Declarative config | Partial (Ansible) | Partial (Ansible) | Partial (Ansible) | Yes (NixOS/modules) | Yes (Guix System) |
| Rollback | Manual | Manual | Manual | Automatic | Automatic |
| Binary cache trust | Distro mirrors | Distro mirrors | Distro mirrors | cache.nixos.org or self-host | ci.guix.gnu.org or self-host |
| Server adoption | Very high (Ubuntu, Debian) | High (RHEL, Rocky, Alma) | Low | Growing | Niche |
| Learning curve | Low | Low | Low | High | High |
| Supply-chain model | Signed debs, curated repos | Signed rpms, curated repos | Signed pkg.tar, rolling | Content-addressed store | Content-addressed store, fully bootstrappable |
### Recommendation for servers
**Primary: apt on Debian 12 or Ubuntu 24.04 LTS**
Rationale: widest third-party support, long security maintenance windows, every
AI tool we ship already has .deb or pip packages. If we need reproducibility, we
layer Nix on top rather than replacing the base OS.
**Secondary: Nix as a user-space tool on any Linux**
```bash
# Install Nix (multi-user, Determinate Systems installer — single command)
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
# After install, use nix-env or flakes
nix profile install nixpkgs#ripgrep
nix profile install nixpkgs#ffmpeg
# Pin a flake for reproducible dev shells
nix develop github:timmy-foundation/sovereign-shell
```
Use Nix when you need bit-for-bit reproducibility (CI, model training environments).
Use apt for general server provisioning.
---
## 2. Containers: Docker vs Podman vs containerd
| Criterion | Docker | Podman | containerd (standalone) |
|---|---|---|---|
| Daemon required | Yes (dockerd) | No (rootless by default) | No (CRI plugin) |
| Rootless support | Experimental | First-class | Via CRI |
| OCI compliant | Yes | Yes | Yes |
| Compose support | docker-compose | podman-compose / podman compose | N/A (use nerdctl) |
| Kubernetes CRI | Via dockershim (removed) | CRI-O compatible | Native CRI |
| Image signing | Content Trust | sigstore/cosign native | Requires external tooling |
| Supply chain risk | Docker Hub defaults, rate-limited | Can use any OCI registry | Can use any OCI registry |
### Recommendation for agent isolation
**Podman — rootless, daemonless, Docker-compatible**
```bash
# Debian/Ubuntu
sudo apt update && sudo apt install -y podman
# Verify rootless
podman info | grep -i rootless
# Run an agent container (no sudo needed)
podman run -d --name timmy-agent \
--security-opt label=disable \
-v /opt/timmy/models:/models:ro \
-p 8080:8080 \
ghcr.io/timmy-foundation/agent-server:latest
# Compose equivalent
podman compose -f docker-compose.yml up -d
```
Why Podman:
- No daemon = smaller attack surface, no single point of failure.
- Rootless by default = containers do not run as root on the host.
- Docker CLI alias works: `alias docker=podman` for migration.
- Systemd integration for auto-start without Docker Desktop nonsense.
---
## 3. Python: uv vs pip vs conda
| Criterion | pip + venv | uv | conda / mamba |
|---|---|---|---|
| Speed | Baseline | 10-100x faster (Rust) | Slow (conda), fast (mamba) |
| Lock files | pip-compile (pip-tools) | uv.lock (built-in) | conda-lock |
| Virtual envs | venv module | Built-in | Built-in (envs) |
| System Python needed | Yes | No (downloads Python itself) | No (bundles Python) |
| Binary wheels | PyPI only | PyPI only | Conda-forge (C/C++ libs) |
| Supply chain | PyPI (improving PEP 740) | PyPI + custom indexes | conda-forge (community) |
| For local inference | Works but slow installs | Best for speed | Best for CUDA-linked libs |
### Recommendation for local inference
**uv — fast, modern, single binary**
```bash
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Create a project with a specific Python version
uv init timmy-inference
cd timmy-inference
uv python install 3.12
uv venv
source .venv/bin/activate
# Install inference stack (fast)
uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
uv pip install transformers accelerate vllm
# Or use pyproject.toml with uv.lock for reproducibility
uv add torch transformers accelerate vllm
uv lock
```
Use conda only when you need pre-built CUDA-linked packages that PyPI does not
provide (rare now that PyPI has manylinux CUDA wheels). Otherwise, uv wins on
speed, simplicity, and supply-chain transparency.
---
## 4. Node: fnm vs nvm vs volta
| Criterion | nvm | fnm | volta |
|---|---|---|---|
| Written in | Bash | Rust | Rust |
| Speed (shell startup) | ~200ms | ~1ms | ~1ms |
| Windows support | No | Yes | Yes |
| .nvmrc support | Native | Native | Via shim |
| Volta pin support | No | No | Native |
| Install method | curl script | curl script / cargo | curl script / cargo |
### Recommendation for tooling
**fnm — fast, minimal, just works**
```bash
# Install fnm
curl -fsSL https://fnm.vercel.app/install | bash -s -- --skip-shell
# Add to shell
eval "$(fnm env --use-on-cd)"
# Install and use Node
fnm install 22
fnm use 22
node --version
# Pin for a project
echo "22" > .node-version
```
Why fnm: nvm's Bash overhead is noticeable on every shell open. fnm is a single
Rust binary with ~1ms startup. It reads the same .nvmrc files, so no project
changes needed.
---
## 5. GPU: CUDA Toolkit Installation Without Package Manager
NVIDIA's apt repository adds a third-party GPG key and pulls ~2GB of packages.
For sovereign infrastructure, we want to control what goes on the box.
### Option A: Runfile installer (recommended for servers)
```bash
# Download runfile from developer.nvidia.com (select: Linux > x86_64 > Ubuntu > 22.04 > runfile)
# Example for CUDA 12.4:
wget https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda_12.4.0_550.54.14_linux.run
# Install toolkit only (skip driver if already present)
sudo sh cuda_12.4.0_550.54.14_linux.run --toolkit --silent
# Set environment
export CUDA_HOME=/usr/local/cuda-12.4
export PATH=$CUDA_HOME/bin:$PATH
export LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH
# Persist
echo 'export CUDA_HOME=/usr/local/cuda-12.4' | sudo tee /etc/profile.d/cuda.sh
echo 'export PATH=$CUDA_HOME/bin:$PATH' | sudo tee -a /etc/profile.d/cuda.sh
echo 'export LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH' | sudo tee -a /etc/profile.d/cuda.sh
```
### Option B: Containerized CUDA (best isolation)
```bash
# Use NVIDIA container toolkit with Podman
sudo apt install -y nvidia-container-toolkit
podman run --rm --device nvidia.com/gpu=all \
nvcr.io/nvidia/cuda:12.4.0-base-ubuntu22.04 \
nvidia-smi
```
### Option C: Nix CUDA (reproducible but complex)
```nix
# flake.nix
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
outputs = { self, nixpkgs }: {
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
buildInputs = with nixpkgs.legacyPackages.x86_64-linux; [
cudaPackages_12.cudatoolkit
cudaPackages_12.cudnn
python312
python312Packages.torch
];
};
};
}
```
**Recommendation: Runfile installer for bare-metal, containerized CUDA for
multi-tenant / CI.** Avoid NVIDIA's apt repo to reduce third-party key exposure.
---
## 6. Security: Minimizing Supply-Chain Risk
### Threat model
| Attack vector | Homebrew risk | Sovereign alternative |
|---|---|---|
| Upstream binary tampering | High (pre-built bottles from CDN) | Build from source or use signed distro packages |
| Third-party GPG key compromise | Medium (Homebrew taps) | Only distro archive keys |
| Dependency confusion | Medium (random formulae) | Curated distro repos, lock files |
| Lateral movement from daemon | High (Docker daemon as root) | Rootless Podman |
| Unvetted Python packages | Medium (PyPI) | uv lock files + pip-audit |
| CUDA supply chain | High (NVIDIA apt repo) | Runfile + checksum verification |
### Hardening checklist
1. **Pin every dependency** — use uv.lock, package-lock.json, flake.lock.
2. **Audit regularly**`pip-audit`, `npm audit`, `osv-scanner`.
3. **No Homebrew on servers** — use apt + Nix for reproducibility.
4. **Rootless containers** — Podman, not Docker.
5. **Verify downloads** — GPG-verify runfiles, check SHA256 sums.
6. **Self-host binary caches** — Nix binary cache on your own infra.
7. **Minimal images** — distroless or Chainguard base images for containers.
```bash
# Audit Python deps
pip-audit -r requirements.txt
# Audit with OSV (covers all ecosystems)
osv-scanner --lockfile uv.lock
osv-scanner --lockfile package-lock.json
```
---
## 7. Recommended Sovereign Stack for Timmy Foundation
```
Layer Tool Why
──────────────────────────────────────────────────────────────────
OS Debian 12 / Ubuntu LTS Stable, 5yr security support
Package manager apt + Nix (user-space) apt for base, Nix for reproducible dev shells
Containers Podman (rootless) Daemonless, rootless, OCI-native
Python uv 10-100x faster than pip, built-in lock
Node.js fnm 1ms startup, .nvmrc compatible
GPU Runfile installer No third-party apt repo needed
Security audit pip-audit + osv-scanner Cross-ecosystem vulnerability scanning
```
### Quick setup script (server)
```bash
#!/usr/bin/env bash
set -euo pipefail
echo "==> Updating base packages"
sudo apt update && sudo apt upgrade -y
echo "==> Installing system packages"
sudo apt install -y podman curl git build-essential
echo "==> Installing Nix"
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --no-confirm
echo "==> Installing uv"
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "==> Installing fnm"
curl -fsSL https://fnm.vercel.app/install | bash -s -- --skip-shell
echo "==> Setting up shell"
cat >> ~/.bashrc << 'EOF'
# Sovereign stack
export PATH="$HOME/.local/bin:$PATH"
eval "$(fnm env --use-on-cd)"
EOF
echo "==> Done. Run 'source ~/.bashrc' to activate."
```
### What this gives us
- No Homebrew dependency on any server.
- Reproducible environments via Nix flakes + uv lock files.
- Rootless container isolation for agent workloads.
- Fast Python installs for local model inference.
- Minimal supply-chain surface: distro-signed packages + content-addressed Nix store.
- Easy onboarding: one script to set up any new server.
---
## Migration path from current setup
1. **Phase 1 (now):** Stop installing Homebrew on new servers. Use the setup script above.
2. **Phase 2 (this quarter):** Migrate existing servers. Uninstall linuxbrew, reinstall tools via apt/uv/fnm.
3. **Phase 3 (next quarter):** Create a Timmy Foundation Nix flake for reproducible dev environments.
4. **Phase 4 (ongoing):** Self-host a Nix binary cache and PyPI mirror for air-gapped deployments.
---
## References
- Nix: https://nixos.org/
- Podman: https://podman.io/
- uv: https://docs.astral.sh/uv/
- fnm: https://github.com/Schniz/fnm
- CUDA runfile: https://developer.nvidia.com/cuda-downloads
- pip-audit: https://github.com/pypa/pip-audit
- OSV Scanner: https://github.com/google/osv-scanner
---
*Document prepared for issue #589. Practical recommendations based on current
tooling as of April 2026.*