quality: dead code, dedup, constants, docs (audit Group E)
Farhan Beg
d8e8033
Quality fixes from the comprehensive audit. No behavior changes — all
syntactic/cosmetic/traceability improvements.
- E1: delete debug-model-options.py. Confirmed dead — not COPY'd into
the image (Dockerfile only copies start.sh, health-server.js,
hermes-sync.py, cloudflare-*.py), no caller anywhere, replaced by the
inline Python probe in health-server.js (/hm/debug/model-options-trace).
Also hardcoded a python3.12 site-packages path that may not match the
container's Python version.
- E7: remove unused 'import time' in cloudflare-proxy-setup.py.
- E11: re-declare ARG HERMES_AGENT_VERSION after FROM so the ENV line
'HERMES_AGENT_VERSION=${HERMES_AGENT_VERSION}' expands correctly
under the classic builder (pre-FROM ARGs are only visible in FROM).
- E12: LOG_ROTATE_BYTES env var replaces the magic 5242880 literal in
the boot log-rotation block.
- E13: record the resolved WebUI commit (git rev-parse HEAD >
/opt/hermes-webui/WEBUI_COMMIT) so a build can be traced to an e…
robustness: crash recovery, signal handling, atomicity (audit Group B)
Farhan Beg
ccb8370
Twelve robustness fixes from the comprehensive audit:
Dockerfile:
- Add tini as PID 1 (ENTRYPOINT ["/usr/bin/tini","--",...]). Bash as PID 1
does not forward SIGTERM to children reliably and doesn't reap zombies
from the piped tee/hermes subprocesses. Tini is transparent — the bash
graceful_shutdown trap still runs the final sync-once before exit.
start.sh:
- Child-process watchdog: replace 'wait $GATEWAY_PID' (which only
caught gateway death — a dashboard/WebUI crash after boot left the
container running with a broken UI while /health stayed green) with
'wait -n' over all supervised PIDs. Any child exiting now triggers a
bounded final sync + exit, so HF restarts the whole Space.
- Kill process groups on shutdown, not 'jobs -p'. Services are pipelines
(cmd | tee) in subshells; killing the subshell PID left hermes bound to
its port. Each service now launches with setsid so kill -- -PGID takes
down the whole group.
- graceful_shutdown stops the sync loop FIRST (SIGT…
fix(proxy): buffer request bodies to avoid chunked Transfer-Encoding, add HERMES_WEBUI_TRUST_FORWARDED_HOST=1
Farhan Beg
1f29b0d
Two fixes for WebUI behind the Node.js reverse proxy:
1. HTTP 501 Unsupported method error: Python BaseHTTPRequestHandler
cannot decode chunked request bodies (Transfer-Encoding: chunked).
Node.js http.request may use chunked encoding when piping req
streams. Fix: buffer the full request body and send it with an
explicit Content-Length header.
2. Cross-origin CSRF mismatch: hermes-webui no longer trusts
X-Forwarded-Host by default. The proxy sets this header, so
browser Origin vs Host checks fail. Fix: set
HERMES_WEBUI_TRUST_FORWARDED_HOST=1 in Dockerfile ENV.
fix(docker): restore proper Dockerfile and add venv chown for hermes user
Farhan Beg
be5c4d4
fix(permissions): chown /opt/hermes/.venv to hermes so auto-updates work
Three changes to keep the HF Logs tab readable and the HF Dataset backup
from growing unbounded:
1. Patch hermes-webui's log_request() at image build time to drop 2xx
responses for high-frequency poll paths (/api/dashboard/status,
/api/health/agent, /api/sessions, /api/profiles, /api/models,
/sw.js, /static/*, etc). 4xx and 5xx still log so debugging works.
2. Rotate \/logs/*.log at boot when any file exceeds 5MB
(rename to .log.1, start fresh). Bounds the disk footprint.
3. Extend hermes-sync.py exclusions to skip *.log, *.log.1, *.log.2,
*.pid, *.tmp suffixes - and treat 'logs/' as a fully-excluded dir
not just a top-level skip. Backup dataset stays clean.