- Resolve decisions.md merge conflict (keep both Codex boundary + Ezra/Bezalel entries) - Update .gitignore: protect bare secret files, exclude venvs and nexus-localhost - Add uniwizard tools (mention watcher, adaptive prompt router, self-grader, classifiers) - Add briefings, good-morning reports, production reports - Add evennia world scaffold and training data - Add angband and morrowind MCP servers - Add diagrams, specs, test results, overnight loop scripts - Add twitter archive insights and media metadata - Add wizard workspaces (allegro, nahshon)
12 KiB
Local-Only Timmy Harness Cutover Plan
For Hermes: treat this as a phased migration plan. Do not restore deprecated cloud loops.
Goal: make this harness boot and operate Timmy locally with no required cloud-model dependency.
Architecture: keep the boundary already written down in ~/.timmy/decisions.md — ~/.hermes is the harness, ~/.timmy is Timmy's workspace. The cutover is not "move Timmy into the cloudless void." It is: strip cloud inference out of the active harness, quarantine legacy remote ops loops, and prove Timmy can think and operate against localhost-only model endpoints.
Tech stack: Hermes harness, local llama.cpp/OpenAI-compatible endpoint, Ollama, Timmy workspace in ~/.timmy, local scripts, local cron jobs.
Ground truth found on 2026-03-29
-
~/.hermes/config.yamlstill has a cloud default:model.default: gpt-5.4model.provider: openai-codexmodel.base_url: https://chatgpt.com/backend-api/codex
-
~/.hermes/config.yamlstill contains cloud escape hatches:- custom provider
Google Gemini fallback_modelpointing at Gemini
- custom provider
-
Built-in cron still has an accidental cloud path:
- job
a77a87392582(Health Monitor) is enabled every 5m model = null,provider = null- per
~/.timmy/OPERATIONS.md, all crons must specify model explicitly - with current live config, null/null means inherit the cloud default
- job
-
~/.timmy/OPERATIONS.mdsays the active system is Hermes + timmy-config sidecar and explicitly says these old loops are deprecated and must not be restored:claude-loop.shgemini-loop.shtimmy-orchestrator.shnexus-merge-bot.shagent-loop.sh
-
Legacy ops scripts in
~/.hermes/bin/still point at VPS/Gitea and the archived dashboard world:timmy-status.shops-panel.shops-gitea.shops-helpers.shclaude-loop.shgemini-loop.shtimmy-orchestrator.shagent-loop.shagent-dispatch.shclaudemax-watchdog.shThese still reference143.198.27.163or cloud agent CLIs.
-
Timmy's local Nexus path is almost right but not fully clean:
~/.timmy/nexus-localhost/nexus/nexus_think.pydefaults to local Ollama- but it still supports optional Groq offload through
groq_worker.py ~/.timmy/nexus-localhost/nexus/groq_worker.pystill callshttps://api.groq.com/openai/v1/chat/completions
-
There is already a local proof tool available:
~/.hermes/bin/local-model-smoke-test.sh- this should become one of the main acceptance checks
-
Important honesty note:
~/.timmy/reports/production/2026-03-28-morning-production-report.mdsaystimmy-configwas moved to a local default- live world state in
~/.hermes/config.yamlstill shows cloud default - trust world state, not yesterday's report
North-star definition
A local-only Timmy harness means:
- No active default model points to a remote API.
- No enabled cron can silently inherit a remote model.
- No required runtime path depends on OpenAI, Gemini, Groq, Anthropic, or other hosted inference.
- Timmy can boot, answer, use tools, and run the local health loop with only localhost model endpoints.
- Cloud-specific scripts may exist only if they are quarantined outside the active path and clearly marked legacy.
Recommended migration shape
Do this in three waves:
Wave 1 — Stop accidental cloud usage
Cut the hidden spend and inheritance bugs first.
Wave 2 — Make local the only active path
Set a single canonical local default. Remove cloud fallback and auxiliary escape hatches.
Wave 3 — Prove and lock it
Run local smoke tests, scrub optional cloud hooks, and add regression checks so the harness cannot quietly drift back.
Task 1: Freeze the current state
Objective: capture the live state before editing anything.
Files:
- Read:
~/.hermes/config.yaml - Read:
~/.timmy/OPERATIONS.md - Capture: current
cronjob list --include-disabled
Steps:
- Copy
~/.hermes/config.yamlto a dated backup. - Save the current cron inventory to a dated note.
- Save a short note with the active risks found above.
Verification:
- backup file exists
- cron inventory is saved
- you can diff before/after safely
Task 2: Kill the inheritance bug in cron
Objective: no enabled cron may run with model=null and provider=null.
Files:
- Runtime cron registry
~/.timmy/OPERATIONS.md
Steps:
- Pause
Health Monitorimmediately or update it to explicit local model/provider. - Audit every remaining enabled cron for explicit local-only routing.
- If a cron just runs a shell health check, replace the LLM wrapper with a pure bash/python script.
Verification:
cronjob list --include-disabledshows no enabled job with null model/providerHealth Monitoris either paused or explicitly local
Task 3: Pick one canonical local default for the harness
Objective: the active harness must have one obvious local mind path.
Files:
- Modify:
~/.hermes/config.yaml
Recommendation: Use the already-present local llama.cpp/OpenAI-compatible path as the day-1 cutover default because it is already represented in config and matches the recent report:
- provider:
custom - model:
hermes4:14b - base URL:
http://localhost:8081/v1
Keep Ollama available for explicit overrides and evaluation (qwen3:30b, timmy:v0.1-q4, etc.), but do not leave the harness split-brained with a cloud default and local side entries.
Steps:
- Change
model.default,model.provider, andmodel.base_urlto the chosen local endpoint. - Keep only local endpoints in the active default path.
- Document the reason in a nearby comment or note: cut cloud first, tune model second.
Verification:
- opening
~/.hermes/config.yamlshows a localhost default - a fresh Hermes session comes up on the local endpoint without extra flags
Task 4: Remove cloud fallback from the active config
Objective: there must be no silent remote escape hatch.
Files:
- Modify:
~/.hermes/config.yaml
Steps:
- Remove the
Google Geminicustom provider from the active config. - Remove or localize
fallback_model. - Review
auxiliary.*anddelegationsections:- if they can run local, pin them local
- if they cannot run local, disable them rather than leaving
provider: auto
- Confirm no active base URL points to a remote inference API.
Verification: Search the active config for these strings and get zero hits:
chatgpt.com/backend-api/codexgenerativelanguage.googleapis.comapi.groq.comanthropicopenai-codex
Task 5: Quarantine legacy cloud and VPS ops scripts
Objective: old remote ops machinery must not remain on the active path where it can be restarted by accident.
Files:
- Review/move from
~/.hermes/bin/:claude-loop.shgemini-loop.shtimmy-orchestrator.shnexus-merge-bot.shagent-loop.shagent-dispatch.shops-panel.shops-gitea.shops-helpers.shtimmy-status.shclaudemax-watchdog.sh
Steps:
- Create a quarantine location such as
~/.hermes/bin/legacy-cloud/. - Move or rename remote-only scripts out of the active PATH.
- Leave a short README there explaining why they were retired.
- Do not delete until the local harness is stable.
Verification:
- the active
~/.hermes/bin/no longer contains scripts that point at143.198.27.163unless they are explicitly retained for non-Timmy infra OPERATIONS.mdand the actual bin directory agree
Task 6: Replace stale status/ops surfaces with local truth
Objective: dashboards and status panels should describe the real local system, not the old VPS/dashboard world.
Files:
- Replace or retire:
~/.hermes/bin/timmy-status.sh~/.hermes/bin/ops-panel.sh~/.hermes/bin/ops-gitea.sh
Steps:
- Remove references to
~/Timmy-Time-dashboardandrockachopa/Timmy-time-dashboard. - Build one small local status script that checks:
- local model endpoint alive
- local session landing directory alive
- local Timmy workspace health
- optional local Nexus process health
- Keep it brutally simple.
Verification:
- the status panel works with Wi-Fi off
- it reports localhost services, not VPS state
Task 7: Scrub optional cloud offload paths from Timmy's runtime
Objective: Timmy's lived runtime should not keep a hidden cloud brain in reserve.
Files:
- Modify:
~/.timmy/nexus-localhost/nexus/nexus_think.py - Modify or quarantine:
~/.timmy/nexus-localhost/nexus/groq_worker.py
Steps:
- Remove the
groq_modelruntime path fromnexus_think.py, or gate it behind a separate legacy plugin that is not imported by default. - If Groq support is kept for archeology, move it to a
legacyorexperimentalnamespace. - Make local Ollama the only supported default thinker in the active Nexus runtime.
Verification:
nexus_think.pycan run withoutGROQ_API_KEY- no active import path requires
groq_worker.py
Task 8: Clean the environment and credentials
Objective: the harness shell should not carry cloud keys it no longer needs.
Files:
- shell startup files
- launch wrappers for Hermes/Timmy
- local env files used by the harness
Steps:
- Inventory active cloud inference keys used by this harness.
- Remove or quarantine the keys for providers you are cutting.
- Keep local-only env vars and local endpoint URLs.
- If other unrelated houses still need cloud keys, move those to house-specific wrappers rather than global shell scope.
Verification:
- a fresh shell used for Timmy starts without OpenAI/Gemini/Groq inference keys
- local Timmy still boots and responds
Task 9: Prove local operation end-to-end
Objective: prove the harness still works after the cut.
Files / commands:
~/.hermes/bin/local-model-smoke-test.sh- a fresh Hermes session
- optional local Nexus startup command
Steps:
- Run
local-model-smoke-test.sh. - Start a fresh Hermes session with no provider overrides and confirm it uses the local default.
- Run one small tool-use task.
- Start the local Nexus thinker and confirm it thinks locally.
- Re-run the health monitor in its new local form.
Verification:
- smoke test passes
- fresh Hermes session uses localhost
- one real tool call succeeds
- Nexus thinker runs without cloud keys
Task 10: Add regression guards
Objective: make it hard to silently drift back to cloud defaults.
Files:
- New guard script, for example:
~/.timmy/scripts/assert_local_only_harness.sh - Optional tests for the active config
Steps:
- Add a script that fails if the active harness config contains remote inference URLs.
- Add a check that fails if any enabled cron has null model/provider.
- Add a check that scans the active bin directory for forbidden strings like:
chatgpt.com/backend-api/codexgenerativelanguage.googleapis.comapi.groq.com
- Exclude vendored benchmark/test fixtures under
~/.hermes/hermes-agent/environments/so the guard only checks active runtime paths.
Verification:
- the guard script passes on the cleaned harness
- reintroducing a cloud URL makes it fail immediately
Definition of done
The cutover is done when all of these are true:
~/.hermes/config.yamlhas a localhost-only default model path.fallback_modelis local or absent.- No enabled cron inherits a cloud default.
- Old remote loops are quarantined out of active
~/.hermes/bin/. - Timmy status/ops scripts no longer point at the archived dashboard or VPS by default.
nexus_think.pyhas no active cloud offload path.local-model-smoke-test.shpasses.- A fresh Timmy/Hermes session works with only local endpoints available.
- Turning off cloud API keys does not break the harness.
Recommended order for the next working session
- Fix the cron inheritance bug.
- Flip the harness default to local.
- Remove cloud fallback entries.
- Quarantine legacy scripts.
- Scrub Groq from
nexus-localhostactive runtime. - Run smoke tests.
- Add regression guard.
That order gets you the biggest sovereignty win first and reduces the chance of half-cut state.
Notes on scope
- This plan is about Timmy's harness, not every possible experimental repo on disk.
- Vendor benchmark configs inside
~/.hermes/hermes-agent/can stay for research as long as they are not part of the active runtime path. - The first victory is not perfection. The first victory is: no active cloud default, no hidden fallback, no accidental remote cron burn.
Sovereignty and service always.