Heavy Hermes × Nous Portal × Gemma 4 Finetune — Architecture Decision
Date: 2026-07-11
Author: Fable 5 (architecture pass, requested by Bharath)
Status: Recommended — extends HEAVY-HERMES-ARCHITECTURE-20260710.md, does not replace it
Question answered: "Use the Nous portal to run the heavy Hermes setup with our finetuned Gemma 4 — rely on Nous for engineering/maintenance while controlling user data, knowledge flow, and the LLM. Bring everything into Hermes with a suitable architecture."
Follow-up: a bigger question — whether to lean on Hermes for reliability reasons (data
and memory included, not just the chat channel) and how to deploy it (Mac-bundled vs. GPU
cloud) — is answered in the same-day companion doc
HERMES-VS-OIMY-ENGINE-RELIABILITY-DEPLOYMENT-20260711.md
(https://cdn.oimyai.com/docs/hermes-vs-oimy-engine-reliability-deployment-20260711.html).
That doc revises nothing here on the Portal/Docker/Gemma-4-wiring questions; it answers a
different question this doc doesn't cover.
Everything below was verified against live systems on 2026-07-11: Hetzner (/opt/oimy-engine,
/root/.hermes, hermes-agent 0.15.2 via pipx), the actual hermes-agent==0.18.2 wheel
downloaded from PyPI and read at source level, Nous's published docs, and a live timed
inference call against the finetune on this box.
0. TL;DR — the four direct answers
-
There are three ways to get "Nous handles the maintenance," and only one of them is right for OiMy. Base Nous Portal is a billing/credential aggregator (one OAuth subscription for 300+ models + a managed Tool Gateway) — it does not host your gateway. Hermes Cloud (portal.nousresearch.com/cloud, currently in preview) is a real Nous-hosted always-on Hermes instance — but it puts the gateway process, which sees every raw family message in plaintext, on Nous's compute, and whether a Cloud instance can even point at a self-hosted model endpoint is undocumented ("No servers, no DevOps, no YAML" is its pitch — a reduced config surface is the likely reading). The third option is Nous's official Docker deployment: their engineering (s6 supervision, auto-restart, pinned versioned upgrades) running on OiMy's own box. Recommendation: the Docker deployment — it captures ~90% of the ops relief with 0% of the data-custody cost. Skip Portal for now; do not put a family-companion gateway on Hermes Cloud (§2, §4).
-
"Bring everything into it" — no, and here is the line. Hermes should become OiMy's unified chat-channel harness (Telegram today; WhatsApp/iMessage-via-Photon later — 0.18.2 ships adapters for all of these). It should not become the front door for the web app, the Rork mobile app, or the voice pipeline, and
api.pyremains the single source of truth for all family data, learning loops, and safety. Full reasoning in §3 — this is the most consequential call in this doc and I'm making it, not hedging it. -
The Gemma 4 finetune plugs in cleanly at the config level — the real gap is serving, not architecture. hermes-agent 0.18.2 supports a direct OpenAI-compatible
base_urlthat bypasses Nous/OpenRouter entirely (verified in source:hermes_cli/config.py:1505, "takes precedence over provider"). But I measured the finetune on Hetzner's CPU Ollama at 1.35 tok/s (60 tokens in 44s) — a 150-token reply would take ~2 minutes. Every vast.ai GPU pod is currentlyexited. There is no production-viable serving endpoint for the finetune anywhere right now. That, not Hermes wiring, is the blocker (§5). -
The history-shape gap flagged in the 2026-07-10 doc is now resolved. Production restored alternating user/assistant history (the session-boundary fix), the dataset plan's addendum v4.4 re-specified training rows as alternating, and Hermes natively keeps alternating history. Three-way convergence — the
history_adapter: user-onlyswap step is deleted for the gold-standard finetune target (§5.3).
1. What exists today (verified, not recalled)
| Component | State on 2026-07-11 |
|---|---|
| hermes-agent | 0.15.2 via pipx (latest: 0.18.2, confirmed on PyPI — 3 minor versions behind) |
| Gateway processes | Two (default = @chittiemma1_bot live for Bharath; oimy-dev = @OimySuperB_bot), both started via nohup … & disown from a manual restart script — zero supervision; a crash means silence until someone notices |
| Vendor patch | gateway/platforms/telegram.py + base.py hand-patched 2026-07-11 (send-degraded window 60s→12s, retry budget 7s→90s) — will be silently lost on any upgrade |
| Hermes model | Both profiles: model.default: openai/gpt-5.4-mini via OpenRouter (thin-router "light Hermes" config) |
| Engines | oimy-engine.service (prod, 8080) + oimy-engine-dev.service (8090), both COMPANION_MODEL=x-ai/grok-4.3, systemd-supervised |
/context endpoint |
Does not exist yet — the Heavy Hermes doc's P2 was never built |
| Finetune artifacts | gemma4-v2lora-fix loaded in Hetzner's local Ollama (CPU: 1.35 tok/s measured, 23s cold load); v3 LoRA evaluated borderline; the gold-standard finetune (17 families / ~874 rows) not yet trained — pilot generation 5/5 families complete |
| GPU serving | All vast.ai pods (V100, 2×A100, H100, RTX3090) exited — zero GPU spend, zero GPU serving |
| Docker | 29.2.1 installed on Hetzner, unused for Hermes |
Two upstream changes in 0.18.2 matter to the prior architecture doc and are confirmed at source level:
- The
pre_llm_callhook protocol is unchanged —agent/shell_hooks.pystill documents and implements{"context": "..."}injection (lines 47–48, 577, 618). The entire Heavy Hermes grounding design survives the upgrade intact. - The 20,000-char SOUL.md cap is no longer a hard ceiling. 0.18.2 makes it a floor:
the cap now scales with the model's context window (6% of window × 4 chars/token, ceiling
500K —
prompt_builder.py:1172-1200), and an explicitcontext_file_max_charsin config.yaml always wins. For Gemma 4 (262K context) the dynamic cap is ~63K chars. The compiled-SOUL/modules design remains right (you still shouldn't paste 135KB of anchors into a static prompt), but the hard 20K panic from the prior doc is relaxed — the ~18K budget becomes a discipline, not a wall.
2. What Nous actually offers, and which piece OiMy should take
Nous's surface area is three distinct things that the question's framing runs together:
(a) Nous Portal — one subscription + OAuth login (hermes setup --portal,
~/.hermes/auth.json) replacing per-provider API keys/billing for 300+ models, plus a
managed Tool Gateway (web search, image generation, TTS, browser automation, optional
cloud terminal sandboxes). Not hosting — the setup flow still ends with you running
hermes gateway run. It solves a credential/billing problem and is orthogonal to both ops
and LLM control.
(b) Hermes Cloud (portal.nousresearch.com/cloud, in preview) — the piece the original framing was actually reaching for: a genuinely Nous-hosted, always-on Hermes Agent instance on Nous's own cloud compute. Pick an instance size (light / regular / larger workflows), deploy in seconds; billed hourly from Nous credit while running, storage-only while stopped, inference and tool usage billed separately; reachable via Telegram, Discord, Slack, Email, CLI; supports scheduled unattended jobs. Marketing pitch: "No servers, no DevOps, no YAML."
(c) The open-source hermes-agent + official Docker image — Nous's engineering (s6-overlay supervision, auto-restart in seconds, profiles as independently supervised services, pinned versioned releases) running on your own machine.
And a fourth option outside Nous entirely: Hermify (hermify.io), a small third-party vendor running hermes-agent fully managed on Telegram.
2.1 The three-way hosting comparison (the real decision)
| Self-host, official Docker | Nous Hermes Cloud | Third-party managed (Hermify) | |
|---|---|---|---|
| Who runs the gateway process | OiMy (Hetzner) | Nous cloud compute | Hermify |
| Who sees raw family messages + session state | Nobody but OiMy | Nous infrastructure | Hermify |
| Ops burden remaining | Compose file + pinned-tag upgrades (~minutes/month) | ~Zero | ~Zero |
Custom self-hosted model (base_url → own Ollama/Gemma-4-FT) |
Confirmed, in source (§5.1) | Unconfirmed — "no YAML" suggests a reduced config surface; not documented anywhere public | Unknown |
/context grounding hook against OiMy's engine |
localhost call, engine stays firewalled | Engine's /context (family rosters, psych profiles, ledgers) must be exposed to the public internet for Nous's compute to reach it |
Same problem, worse |
| Maturity | The core product, 0.18.2, battle-tested | Preview | Small vendor |
| Cost | Existing Hetzner box | Hourly compute + storage + separate inference/tool billing | Subscription |
2.2 Recommendation, stated as an opinion because it is one
Self-host via the official Docker image. Do not put OiMy's gateway on Hermes Cloud — and
this is a data-category judgment, not a hedge. The gateway is the one component that sees
everything in plaintext, before and after every model call: kids' names and routines,
medication reminders, custody and co-parenting conflict, mental-health-adjacent signals —
exactly the data OiMy's whole pitch says stays under the family's (and Bharath's) control.
Hermes Cloud moves that component onto Nous's compute, where OiMy has no data-residency
terms, no access guarantees, and a preview-stage product's stability. And under the Heavy
Hermes design it gets worse, not better: the per-turn /context grounding call would carry
entity facts, psych profiles, and constraint ledgers to Nous's cloud every turn, and OiMy's
engine — localhost-only today for these endpoints — would have to be opened to the public
internet to be reachable from there. The compensation for all of that is relief from ops
work that, on a box OiMy already runs 10 systemd services on, amounts to docker compose up
plus a pinned-tag bump occasionally. The trade is badly lopsided. For a family-companion
product, the gateway is product infrastructure, not a commodity to outsource.
Two honest qualifiers:
- The load-bearing unknown, flagged plainly: I could not confirm whether a Hermes Cloud
instance supports provider: custom/base_url at all (the page is bot-protected; the
docs don't cover Cloud's config surface; the open-source agent supports it, but preview
managed products often expose less). If it doesn't, Hermes Cloud can't even meet the
"controlling the LLM part" requirement and the comparison ends there. If Bharath wants
this settled empirically, it's a cheap test: spin up the smallest Cloud instance, try
pointing it at an authed tunnel to the Mac-mini Ollama, and see. Worth doing only as
curiosity — a yes would not change my recommendation, because the data argument above
doesn't depend on it.
- Where Hermes Cloud would be reasonable: a non-OiMy utility agent (Bharath's personal
research/scheduling assistant, ops briefings) with no family data in the loop. Keeping
such things off the OiMy box is arguably a plus. It is the family data specifically that
makes Cloud wrong here.
Hermify: recommend against, same reasoning at higher intensity — the Telegram bot token
and every family message in plaintext in a small third party's hands, to save one
docker compose up. Not a close call.
2.3 Portal verdict (the billing/tools piece, separable from hosting)
Do not adopt Portal now. OiMy already has the model access it needs (OpenRouter for
Grok 4.3, its own endpoint for Gemma 4), and it uses none of the Tool Gateway tools in the
family-conversation flow. If OiMy later wants web search or image generation inside Hermes,
revisit — with the explicit understanding that those specific tool calls would transit Nous,
and scope them accordingly (e.g., tools enabled for logistics/planning turns, never for
emotional-support turns). Nothing in this architecture forecloses adding Portal later; it's
one hermes setup --portal away and orthogonal to everything else in this doc.
3. "Bring everything into it" — the recommendation
Recommendation: Hermes becomes OiMy's chat-channel layer. api.py remains the product's
core engine and the front door for everything that isn't a chat platform. Concretely:
Goes into Hermes (now or on the roadmap):
- Telegram (already there — the live default and oimy-dev profiles).
- The heavy-Hermes composition role per the 2026-07-10 doc: Hermes composes replies natively,
grounded per-turn by /context, writing back via /context/writeback.
- Later, other chat channels: 0.18.2 ships first-party adapters for WhatsApp, Discord, SMS,
email, and — notably — Photon (plugins/platforms/photon). OiMy's iMessage today runs
through its own oimy-photon-imessage.service; when that service next needs real work, the
right move is to evaluate folding iMessage into the same Hermes gateway as another platform
on the same profile, giving every chat channel one harness, one SOUL, one session store, one
grounding hook. That is the honest meaning of "bring everything into it."
Stays on api.py (permanently, by design):
- The web app and the Rork mobile app. These are API clients, not chat platforms. The Rork
spec already commits to an OpenAI-compatible SSE endpoint on the engine so ElevenLabs' voice
agent can point at OiMy's own reasoning — Hermes' gateway is a chat-platform bridge and
offers no client-facing streaming chat API to build a mobile app against. Routing an app
through a Telegram-shaped harness would add a hop and subtract streaming.
- All family data and learning loops: entity graph, deep profile, H3.0, Honcho, constraint
ledger, the DB. Hermes' own memories/ stays disabled for family facts (unchanged from the
prior doc — two long-term memories about one family is how you get contradictions).
- Safety and post-generation guardrails (roster/ledger/clinical checks) and the
registration/onboarding/provisioning flows that already exist on the web stack.
Why not make Hermes the front door for everything? Four reasons, in order of weight:
- Asset gravity. Everything defensible about OiMy — the tested anchors, the deep-profile pipeline, the H3.0 engine, the constraint ledger, the eval-hardened guardrails, the data — lives in the engine. Hermes brings a harness (sessions, tools, channels, supervision), not a data model. Moving the product's center of gravity into a third-party harness inverts who owns what for zero capability gain: everything Hermes needs from the engine it can get through two narrow endpoints.
- Churn exposure. hermes-agent moved 0.15.2→0.18.2 in ~40 days and reorganized its
platform code in that window (
gateway/platforms/telegram.pyno longer exists; it's nowplugins/platforms/telegram/adapter.py— I verified this while checking the patch, §4.2). A narrow contract (/context,/context/writeback, per-sender JWTs) survives that churn; a deep integration would be rewritten every quarter. - The competing-thesis point from the prior doc (§6.9), now with a sharper answer. Heavy Hermes vs. engine-as-brain was left as an open strategic question. Making Hermes the chat-channel brain while the engine remains the product brain is not a dodge of that question — it's the resolution: the harness competes on conversation orchestration, where it is genuinely better (sessions, tools, multi-channel, supervision); the engine competes on knowledge, memory, learning, and safety, where it is genuinely better. Neither side holds the other's job.
- Provisioning reality. Hermes-side identity is a hand-minted per-sender JWT env var. The engine side has real registration, onboarding, family joins, and per-user container provisioning. The system of record for "who is this user" cannot be the layer where adding a user means editing an env file.
One consequence worth stating: under this design the engine's /chat remains a first-class
public API (web/mobile), and heavy Hermes is a second composition path for chat channels.
The /context + writeback contract is what keeps those two paths from diverging — it is
mandatory, not optional, and it must ship before any heavy-Hermes traffic (it is P2 in the
prior doc's build order and still unbuilt).
4. The Docker migration — the actual "let Nous handle maintenance" move
4.1 Recommendation
Move both gateway profiles from bare pipx + nohup to the official image, pinned:
# /opt/oimy/hermes/docker-compose.yml (new)
services:
hermes-gateway:
image: ghcr.io/nousresearch/hermes-agent:0.18.2 # pin; never :latest
restart: unless-stopped
volumes:
- /root/.hermes:/root/.hermes # profiles, sessions, state.db, auth, hooks
env_file: /root/.hermes/.env
The image's s6-overlay supervises the gateway (and each profile as an independent service),
restarting within seconds of a crash. Combined with restart: unless-stopped at the Docker
level and the box's existing watchdog pattern, this closes the "bot dies silently at 3am"
class entirely. Upgrades become: change the pinned tag, docker compose pull && up -d,
with instant rollback to the previous tag. This — not Portal — is where "rely on Nous for
the engineering" is actually realized: they maintain the runtime, the supervision, the
platform adapters, and the upgrade path; OiMy maintains a compose file and a config.
(A lighter alternative — wrapping the existing pipx install in two systemd units with
Restart=always — would fix supervision alone. I recommend the Docker path anyway because it
also fixes version pinning, makes the 0.15.2→0.18.2 jump atomic and reversible, and ends the
hand-patched-vendor-package situation. If Docker migration stalls for any reason, do the
systemd wrap immediately as a stopgap; unsupervised nohup should not survive the week.)
4.2 The hand-patched vendor fix — disposition, verified against 0.18.2 source
The 2026-07-11 manual patch had two parts. I read the 0.18.2 source to determine what upgrade does to each:
- The 60-second degraded-send window (
telegram.py, probe delay 60→12s): superseded by a better upstream fix — drop it. In 0.18.2 (plugins/platforms/telegram/adapter.py:2115-2125, referencing upstream issue #35205), a successfulstart_polling()reconnect now clears_send_path_degradedimmediately, instead of leaving sends hard-refused until a 60s heartbeat probe. The 60s probe still exists but is demoted to a defensive re-check. The exact failure Bharath hit (reply generated during the post-reconnect refusal window, silently dropped) can no longer occur in that form. Upstream's fix is strictly better than our 12s mitigation. - The send-retry budget widening (
base.py, ~7s→~90s): NOT upstream — but no longer load-bearing. 0.18.2's_send_with_retrystill defaults tomax_retries=2, base_delay=2.0(~7s total). However: (a) the degraded-window interaction that made the 7s budget fatal is gone, so the residual exposure is only "network actually down for >7s at the exact moment of send"; (b) 0.18.2 now sends the user an explicit delivery-failure notice when retries exhaust, instead of failing silently. Accept the upstream defaults; do not re-patch. Re-patching inside a Docker image means maintaining a fork — the cost now exceeds the benefit. Watch item for the soak period: any recurrence of a generated-but-undelivered reply in gateway logs; if it recurs, file it upstream (Nous took #35205 and shipped it — they accept exactly this kind of report) rather than re-forking.
4.3 Migration sequencing (risk: Bharath's live daily bot)
- Stand up the compose file running only a copy of the
oimy-devprofile (test bot) on 0.18.2, with the pipxoimy-devgateway stopped. The two bots are separate Telegram bot tokens — the livedefaultbot is untouched. Verify: message round-trip, JWT routing to the dev engine, session persistence intact (sessions/state.db ride along in the volume), kill -9 the container process and watch s6 restart it. - Soak 2–3 days of real use on the test bot.
- Migrate
default(the live bot) the same way, in a low-traffic window. Rollback at any point:docker compose down+ restart the pipx gateway via the existing manual script — the pipx install stays on the box, patched and working, until the soak completes. Delete it (and its patch) only afterdefaulthas run a clean week on Docker. - Config deltas to carry consciously across 0.15.2→0.18.2: re-verify the two profiles'
config.yamlagainst 0.18.2's schema (hermes doctorequivalent / first-boot log), re-verify the SKILL.md routing behavior, and note the telegram adapter is now a plugin (any log-path or module-name assumptions in the watchdog/watcher scripts need updating —oimy-hermes-watcher.pygreps should be checked against the new layout).
5. The Gemma 4 finetune behind Hermes
5.1 The wiring is genuinely a config flip — confirmed
0.18.2's model config supports a direct OpenAI-compatible endpoint that bypasses every
managed provider (hermes_cli/config.py: base_url — "direct OpenAI-compatible endpoint
(takes precedence over provider)"), plus named custom_providers. Ollama, vLLM, SGLang, and
llama-server are all documented backends. So the target config for the heavy profile is:
model:
default: gemma4-gold-ft # or gemma4-v2lora-fix for interim testing
provider: custom
base_url: http://<oimy-serving-endpoint>/v1
api_key: "" # local/private endpoint
fast: openai/gpt-5.4-mini # keep via openrouter for routing/classification
No Portal, no Nous traffic, no OpenRouter on the companion path. This satisfies "controlling the LLM part" completely — it always did; Portal was never part of that equation.
5.2 The real gap: there is nowhere to point base_url at today
Measured on Hetzner this morning: gemma4-v2lora-fix on local CPU Ollama generates at
1.35 tok/s with a 23s cold load. A typical 150–250 token Oi reply would take 2–3 minutes.
Every vast.ai GPU pod is exited (deliberately — zero idle spend), and vast.ai is ruled out
for anything production-facing anyway (no uptime guarantee; two real incidents already).
The Mac mini path is real but is a home machine behind a tunnel — acceptable for the
Bharath+Gayatri family test, not for anything beyond it.
Recommendation (unchanged from the serverless research, now with a concrete consumer):
- Family-test phase: serve from the Mac mini (Ollama, gemma4-v2lora-fix or the
gold-standard finetune when trained) via the already-planned Cloudflare tunnel; Hermes
base_url points at the tunnel. Cost: $0. Honest caveat: home-machine availability.
- Anything past the family test: Modal, L4 tier (~$0.80/hr, per-second billing,
memory-snapshot cold starts) running the exact existing Ollama/GGUF container — zero
re-validation of the hand-won LoRA-scale fix, which is the reason Fireworks/Together were
ruled out. RunPod Serverless ($0.69/hr) is the budget fallback.
This serving decision is a prerequisite for the swap, and it is the only genuinely new infrastructure in this whole plan.
5.3 The history-shape gap from the prior doc: resolved — with one residual check
The 2026-07-10 doc flagged (§4.0.3) that Hermes' native alternating user/assistant history
conflicted with production's then user-only history and the training rows shaped to match.
Since then, in order: the session-boundary fix restored assistant turns to production history
(A/B-proven, 3/3 vs 0/3 on stale-question grounding); dataset-plan addendum v4.4 re-specified
training-row history as alternating; zero training rows existed before the correction. So:
production, the gold-standard training data, and Hermes' native session history now all
agree on alternating. The history_adapter: user-only step is deleted from the gemma4-ft
target in modules.yaml. One less moving part, and Hermes' native behavior is now exactly
the trained shape.
Residual checks, honestly scoped:
- v2/v3 LoRA adapters were trained before the reversal, against contexts shaped by the
old convention. If either is used as the interim Hermes-backing model (rather than just
local smoke tests), expect mild out-of-distribution behavior on history handling and don't
read it as a verdict on the architecture. The gold-standard finetune is the real target.
- The block-format contract (§4.0.2 of the prior doc) still stands and is still open: the
/context blocks and the training renderer must be byte-format-identical, single-sourced.
This is a build-time requirement on P2 (/context) and on the still-unwritten
train_v3.py/assemble_contexts.py pipeline — the right move is for the training pipeline
to literally call /context's formatter. Nothing has changed here except that it must now
be enforced in code that is about to be written, which is the cheapest moment to do it.
- Anchor top-K, module ablations, two-model harness question (§6.8): all unchanged from
the prior doc; all post-swap tuning, none of them blockers.
5.4 What "heavy Hermes on the finetune" means for SOUL.md
With 0.18.2's dynamic cap (~63K for Gemma 4's 262K window, or any explicit
context_file_max_chars), the compiled-SOUL budget is a choice rather than a ceiling. Keep
the ~18K discipline anyway for the Grok target, and keep the --target gemma4-ft compile
shrinking it to ~6K (safety + grounding + telegram + harness): a 12B model's effective
attention is the real budget, not the harness limit, and the finetune is supposed to have
absorbed the rest. The manifest/build_soul.py design from the prior doc carries over
unmodified.
6. Data-custody boundary — the plain-language statement
Under this architecture, stated simply enough to repeat to an investor or a spouse:
Never leaves OiMy's own infrastructure:
- The family database: every profile, entity graph, inference, constraint ledger, message
history. (Hetzner, and only Hetzner.)
- The knowledge assets: anchors, prompts, SOUL modules, manifests.
- On the Gemma-4-finetune path: the model weights and every prompt/response — the model
is served from an OiMy-controlled endpoint (base_url), and that traffic never touches
Nous, OpenRouter, or any model vendor. The finetune's weights contain only the 17
synthetic families; no real family is ever in the weights.
- Hermes itself runs entirely on OiMy's server (open-source package, self-hosted gateway).
Nous receives no message traffic, no telemetry of conversation content, nothing —
with no Portal login there is no Nous account in the loop at all.
Leaves OiMy's infrastructure, by explicit choice, exactly as today: - Messages transit Telegram's servers (inherent to the channel — same for WhatsApp/ iMessage later). - On the Grok 4.3 path (current production + the heavy-Hermes comparison arm): prompts including injected context go to OpenRouter/xAI per call, stateless. This exposure ends per user the day that user's traffic moves to the finetune path. - Deep-inference (Opus via OpenRouter) and Honcho (api.honcho.dev) receive conversation-derived content today on the engine side. This predates and is orthogonal to Hermes — but if the custody statement above is going to be said out loud to others, Honcho is the piece worth re-examining separately, since it holds derived insight about real users on a third-party service. - If Modal serves the finetune: prompts transit an OiMy-owned container on Modal's GPUs — same trust category as Hetzner (infrastructure provider), not a model vendor. The Mac mini option keeps even this at home.
Nous's position in this picture: software vendor, not data processor. They ship the
harness; they see nothing. That is the correct and fully achievable version of "rely on Nous
for engineering while controlling the data" — and it requires not using the three things
that would change their position: the Portal Tool Gateway (tool inputs transit Nous),
Hermes Cloud (the gateway itself — raw messages, session state, and every /context
payload — would run on Nous compute), or a third-party host like Hermify.
7. Phased rollout (each step verifiable and reversible; prod Grok 4.3 traffic never at risk)
Phase 0 — hygiene (this week, no user-facing change):
- Git-track /root/.hermes configs + the new compose file alongside the pending
/opt/oimy-engine git setup (the standing ask from the overnight log — same motivation).
- Fix the GET /token unauthenticated-JWT-mint hole on the engine before any new surface
(Hermes heavy profile, Rork, wife's account) points at it. ~1hr, already spec'd in the
Rork doc, still unapplied.
Phase 1 — Docker migration (per §4.3): dev profile → soak → live profile. Rollback: pipx gateway stays installed until a clean week passes. Exit criteria: zero silent drops, s6 restart proven, watcher scripts updated for the plugin layout.
Phase 2 — Heavy Hermes on Grok 4.3 (the prior doc's P0–P4, unchanged, now on Docker):
new oimy-heavy profile + third bot token, /context + /context/writeback on the dev
engine (8090), fetch_grounding.sh hook (protocol confirmed intact in 0.18.2), compiled
SOUL, side-by-side eval vs. light Hermes vs. engine-direct. Prod engine untouched. This
phase exists so the heavy architecture is proven on a strong model before the finetune
enters the picture — failures then localize to the model, not the plumbing.
- Build /context's block formatter as the shared module the training pipeline will also
import (§5.3's contract, enforced at birth).
Phase 3 — finetune serving + swap (gated on Phase 2 eval and on the gold-standard finetune
existing):
- Stand up serving (Mac mini tunnel for family test; Modal L4 beyond that), smoke the
endpoint with the LoRA-scale fix checks (3/3 clean generations, no thinking-runaway).
- build_soul.py --target gemma4-ft + model.base_url flip on the heavy profile — the
documented two-command swap, minus the now-deleted history adapter.
- Run the same Phase 2 eval suite against the finetune arm. Interim runs may use
gemma4-v2lora-fix to shake out serving, but per §5.3 don't score the architecture on a
pre-reversal adapter.
- Rollback at any moment: recompile --target grok-4.3, flip base_url back.
Phase 4 — promotion (Bharath's call, with Phase 3 data): move real family traffic
(starting with the Bharath+Gayatri test cohort) to the heavy profile; decide per-channel
whether light-Hermes/engine-direct paths retire; only then consider folding iMessage/WhatsApp
into the same gateway (§3). Prod /chat for web/Rork continues unchanged throughout.
8. Open questions (genuinely open, needing Bharath or data — not hedges)
- Honcho (§6): keep, self-host, or absorb into the engine? The only third party holding derived real-user insight. Decide before the custody statement is used externally.
- Proactive-messaging ownership (prior doc §6.5, still undecided): engine rhythm loops vs. Hermes-side initiative — pick one initiator per user before the heavy profile carries a real family, or the family gets double-texted.
- Guardrail parity (prior doc §6.3, still undecided): is the heavy path allowed to be less mechanically governed than the engine path? Needs Phase 2 eval numbers on Grok/finetune leak rates to be answered honestly.
- Which finetune is "the" finetune: v3's full-30 eval read, and the gold-standard training run's timing, determine whether Phase 3 targets an interim adapter or waits. The architecture is identical either way; the promotion decision is not.
- Modal vs. Mac-mini as the durable serving story — cost/availability tradeoff that only matters at Phase 4; flagged now so it isn't discovered then.
- Hermes Cloud's custom-model support (§2.2) — unconfirmed, and unconfirmable without an account-holder test. Only worth resolving if Bharath wants the empirical datapoint; it does not gate anything in this plan.
Appendix — facts verified for this document (2026-07-11)
- Portal ≠ hosting: hermes-agent docs,
integrations/nous-portal(localhermes setup --portal, self-run gateway) — per orchestrating-session doc fetch. - Hermes Cloud: portal.nousresearch.com/cloud — page is behind bot protection (HTTP 429 on
direct fetch); existence, preview status, instance sizes, billing model, and the "No
servers, no DevOps, no YAML" positioning confirmed via search-indexed page content
(2026-07-11). Custom
base_urlsupport on Cloud instances: not documented anywhere publicly reachable — treated as unconfirmed throughout this doc. The main hermes-agent docs contain no Hermes Cloud configuration section. - Docker image + s6 supervision + pinned tags: hermes-agent docs
user-guide/docker. hermes-agentlatest = 0.18.2 (PyPIpip index versions, checked from Hetzner).- 0.18.2 wheel inspected at
/tmp/hermes018/pkgon Hetzner: - hook protocol unchanged:
agent/shell_hooks.py:47,577,618. - SOUL cap now dynamic:
agent/prompt_builder.py:1172-1200(context_file_max_charsoverride; 6%-of-window dynamic cap, 20K floor, 500K ceiling). - telegram adapter relocated:
plugins/platforms/telegram/adapter.py. - degraded-flag cleared on reconnect:
adapter.py:2115-2125(upstream #35205);HEARTBEAT_PROBE_DELAY = 60remains as defensive probe only (adapter.py:2342). - retry budget unchanged upstream:
gateway/platforms/base.py:4073(max_retries=2, base_delay=2.0); delivery-failure notice on exhaustion (docstring, same function). - custom endpoint:
hermes_cli/config.py:1503-1506(provider: custom,base_url"takes precedence over provider"). - platform adapters present: telegram, whatsapp, photon, discord, sms, email, matrix,
slack, teams, et al. (
plugins/platforms/). - Live gateway state: two
nohupprocesses (PIDs 422986/423179, started 01:27 from a manual restart script), pipx hermes-agent 0.15.2, vendor patch backups dated 2026-07-11 01:26. - Finetune CPU serving measured live:
gemma4-v2lora-fixvia Hetzner Ollama/api/generate— 60 tokens / 44.4s eval = 1.35 tok/s, 22.9s load. Host: 16 vCPU, 30GB RAM, no GPU (nvidia-smiabsent). - Engines: prod+dev both
COMPANION_MODEL=x-ai/grok-4.3(read from/proc/<pid>/environ, notsystemctl show). - History convention: session log §1.4 (assistant turns restored, A/B 3/3 vs 0/3) + dataset plan addendum v4.4 (alternating, zero rows pre-correction).
- vast.ai: all pods exited per 2026-07-10 memory; serverless research (Modal L4 rec, Fireworks/Together ruled out for GGUF) per 2026-07-06 memory.
- Publishing mechanism:
cdn.oimyai.com= nginx root/var/www/models(autoindex), docs at/var/www/models/docs/*.html.