Repository navigation
feat!: Migrate to Hermes Agent (v2.0.0) - #31
Conversation
BREAKING CHANGE: all instances now run NousResearch Hermes Agent instead of OpenClaw. Fresh-install cutover: no data/session import, workspaces are recreated from templates. - images: Dockerfile.user / admin/Dockerfile on nousresearch/hermes-agent:stable - compose: admin builds locally, hermes_data -> /opt/data, dashboard 9119 (port map 18789 / 18790+N preserved), HERMES_UID/GID=1000 - configs: instances/_template/hermes_config.yaml.template + admin/config.yaml (quota-proxy provider, api_mode anthropic_messages, voice.stt openai) - scripts: add-user.sh rewritten for hermes_data/.env scheme (TELEGRAM_BOT_TOKEN, TELEGRAM_ALLOWED_USERS, HERMES_GATEWAY_TOKEN); backup/fix-permissions/autoupdate/migrate-instances updated; refresh-oauth.py and update-token.py removed (OAuth lives in CLIProxyAPI) - legacy cleanup: openclaw.json templates, legacy workspace migrations and all openclaw/clawdbot/moltbot references removed (grep = 0) - docs: README x2, CLAUDE.md, docs/SECURITY.md rebranded; migration plan in docs/migration-hermes.md
Blockers/high:
- add-user.sh: TG_ID required (empty allowlist = silent dead bot), root
.env required for quota registration, trailing-newline guard before
append, first-free-port scan, SOUL.md copied to hermes_data (Hermes
reads persona from ~/.hermes), docker compose config validation
- scripts/provision-hermes-data.sh + make bootstrap: hermes_data for
admin and existing instances (dirs, .env mapped from legacy var names,
SOUL.md, chown 1000:1000)
- legacy OAuth scripts removed: refresh-anthropic-token.sh,
refresh_token.py (+CLAUDE.md row)
- sync-instances.sh: workspace path fixed (legacy -workspace layout was
silently dead); WORKSPACE_PARENT removed everywhere
- compose: group_add ${DOCKER_GID:-999} (was hardcoded 988), honest
docker.sock comment
- Dockerfiles: pinned v0.22.5 (no floating stable + 5-min autoupdate);
admin installs only docker-compose-plugin (host CLI is mounted anyway)
- template config: provider anthropic + base_url override (invented
'quota-proxy' provider name could fail validation)
Majors/minors:
- backup.sh: excludes .env secrets, chmod 600 archive
- fix-permissions.sh: chown 1000:1000 hermes_data
- migrate-instances.py: load_migration wrapped in try, dead code removed
- .env.example / CONTRIBUTING / README x2 / SETUP: TELEGRAM_ALLOWED_USERS,
HERMES_GATEWAY_TOKEN, OPENAI_API_KEY
- .gitignore: OpenClaw-era entries removed
- template workspace ships .migrations_applied (fresh installs skip the
20 historical migrations)
- docs/migration-hermes.md: VPS deploy runbook (token preservation!),
honest rollback section, Q&A closed with doc evidence
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
Security findingsAdvisory findings (1)ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
✅ Security Check Results
Все проверки пройдены. |
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: c45bafbb39
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
| # Персона: Hermes читает SOUL.md из ~/.hermes (=/opt/data), источником истины служит workspace/SOUL.md | ||
| if [ -f "$DIR/workspace/SOUL.md" ]; then | ||
| if [ ! -f "$DIR/hermes_data/SOUL.md" ] || ! diff -q "$DIR/workspace/SOUL.md" "$DIR/hermes_data/SOUL.md" >/dev/null 2>&1; then | ||
| cp "$DIR/workspace/SOUL.md" "$DIR/hermes_data/SOUL.md" |
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Security: Reject symlinks before synchronizing SOUL.md
An authenticated user or compromised user bot can exploit this when an operator next runs make deploy: both workspace and hermes_data are writable by the user container, so it can replace workspace/SOUL.md with a symlink to ../../../.env. This host-side cp dereferences the link and copies the root .env into the user's /opt/data/SOUL.md, exposing Anthropic, quota-admin, broker, monitor, and service credentials. Use descriptor-based no-follow copies or keep the authoritative source outside user-writable mounts.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 78ba1e9: rejected symlinks across scripts/provision-hermes-data.sh (using O_NOFOLLOW + S_ISREG descriptor copy), scripts/sync-instances.sh (! -L + cp -P), and scripts/migrate-instances.py (is_symlink() + follow_symlinks=False), and added regression coverage in tests/test_symlink_protection.py.
🤖 I have created a release *beep* *boop* --- ## [1.0.0](v0.6.0...v1.0.0) (2026-10-26) ### ⚠ BREAKING CHANGES * Migrate to Hermes Agent (v2.0.0) ([#31](#31)) ### Features * Add Enterprise 1000-user scaling, SSE quota accounting, and bulk provisioning ([#33](#33)) ([02997fb](02997fb)) * Migrate to Hermes Agent (v2.0.0) ([#31](#31)) ([c68d20e](c68d20e)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
Complete big-bang migration of CortexForge v2.0.0 from legacy OpenClaw to NousResearch Hermes Agent (
nousresearch/hermes-agent:v0.22.5) with zero legacy references remaining.Type of Change
Changes
instances/Dockerfile.userandinstances/admin/Dockerfiletonousresearch/hermes-agent:v0.22.5; updateddocker-compose.ymlmounts (hermes_data:/opt/data,workspace:/opt/data/workspace), dashboard port (9119),HERMES_UID/GID=1000, and parameterizedDOCKER_GID.instances/_template/hermes_config.yaml.templateandinstances/admin/config.yaml; createdscripts/provision-hermes-data.sh(make bootstrap/make deploy) to provisionhermes_data/,.env,SOUL.mdsync, and1000:1000ownership while strictly isolating admin vs user quota keys.scripts/add-user.sh(mandatoryTG_ID, fail-fast root.envcheck, first-free port allocation,SOUL.mdsync); hardenedscripts/backup.sh(umask 077,chmod 600, excluded.envandhermes_data/ssh/*); removed legacy OAuth scripts and historical OpenClaw migrations; fixed all ShellCheck warnings.docs/migration-hermes.md; updatedREADME.md,README.ru.md,CLAUDE.md,docs/SETUP.md, andCONTRIBUTING.md.Testing
python3 -m unittest discover tests/ -v— 130/130 tests passpython3 .github/scripts/ai_security_check.py— no findingsshellcheck scripts/*.sh— 0 warnings / 0 errorsmake security-check— verifiedDocumentation
README.md,README.ru.md)docs/updated (docs/SETUP.md,docs/SECURITY.md,docs/migration-hermes.md)CHANGELOG.mdentry added (or release-please will handle it)Security
.env.examplesubprocess.run()calls without input validationNotes for Reviewer
Reviewed across 3 full rounds by the agent team (Megatron, Ratchet, Quintus) until zero blocker/critical/high/medium issues remained.