Repository navigation
feat(integrations): connect named Hermes profiles (#7674) - #7700
Conversation
Hermes keeps one home per profile (<root>/profiles/<name>/config.yaml, run with HERMES_HOME pointed at it), and Connect only ever wrote the default profile. Named profiles are now discovered with Hermes' own rules (id grammar, identity markers, .deleted tombstones, _hermes_root_of root derivation, Windows %LOCALAPPDATA%\hermes) and selected explicitly with profile=<name>. Each named profile owns integrations/hermes-profiles/<name>/ (records, journal, snapshots), so apply, disable, replace, undo and history deletion stay inside that profile. Without a selector, or with profile=default, the default profile, root store and paths behave exactly as before. Only providers.opencodex is written; model.default is never touched. A scoped request skips every Aside delegation and sees only Hermes operations; flight keys carry the profile so a second profile is busy rather than joined; a guarded store facade and the writer's synchronous guard (restore now honors it too) re-check the pinned profile directories, link and junction refusal, tombstones and the owner record path before any disk access. Uninstall pins and guards every owned profile. Connect -> Hermes lists profiles with per-profile status; docs-site guide and structure/clients/hermes.md describe the contract.
|
Caution Review failedThe pull request is closed. Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
✅ Deterministic PR hygiene checks passed. |
…reGuard for Hermes boundaries
Local CI-equivalent (Linux) at d3718f7PASS under the temporary base-identical exception; raw failed exits are retained below. Host Environment: Selectors: ci=True, GUI=True, docs=True, structure=True. The requested direct structure check runs as well.
Test-file coverage: 2602/2602 general files, no gaps/duplicates:
Every batch uses
Combined command counts: 55892 pass / 0 fail / 174 skip. Failed command/batch exits stay failed. Failures:
Base command ledger (once per base/runtime/file or exact batch, cached across these PRs):
Earlier head snapshots (superseded for the current verdict):
NOT RUN: GitHub Actions checkout/setup/upload-artifact infrastructure and other platform/job legs outside this assignment; checkout, Bun role setup and dependency artifacts are reproduced locally Fresh final PR head Exact per-batch file lists, exits and logs:
UTC: 2026-10-25T00:40:34.601458+00:00 |
# Conflicts: # scripts/test-layout/layout-clients.json
macOS real-machine verification addendum (owner lane mac3): INCOMPLETE, stopped by the managerHead
The CLI help smoke exited 0 on every shard. The shards cover 870 + 870 + 871 = 2611 files, equal to the control membership. INCOMPLETE / NOT RUN: No changes, pushes, approvals, or merges were made. |
Local CI-equivalent (Linux) at 6d79ad1PASS under the owner-approved local verification rule. No INTRODUCED failures: 27 BASE-IDENTICAL assertion failures and one BASE-IDENTICAL process-exit failure are recorded below; raw nonzero commands remain failed. This evidence applies only to Host: Fresh detached worktree; Failure comparison: freshly fetched Full primary general-suite coverage: 2604 files, 250 batches, no missing/duplicate files. Dedicated storage-policy and api-usage files run separately. All requested head-command totals: 55927/27/174 pass/fail/skip, excluding base comparisons and diagnostic reruns. CI selectors: ci=true, gui=true, docs=true, structure=true. GUI lint/tests/build and docs build were selected and executed. Command results (counts are pass/fail/skip; 0/0/0 for commands without test counters):
The original Failure classification:
Introduced-failure batch reruns: NOT RUN because no failure was classified INTRODUCED. Every primary batch: exit and pass/fail/skip counts
Base comparison commands
NOT RUN: GitHub Actions service steps (checkout/setup/upload-artifact) and job/platform legs outside the requested verification scope; checkout, pinned Bun and dependencies reproduced locally; npm-global/platform smoke legs outside the explicitly requested Linux check set. Exact commands, ordered per-batch file manifests, exit/count logs, base failures and source-status evidence are retained on this host under |
# Conflicts: # scripts/test-layout/layout-clients.json # tests/fixtures/test-layout-expected.json
|
Integration evidence (owner lane M2, maintainer integration): independent gpt-6.1-sol reviews R1-R4, final review and the delta review of d3718f7 PASS; later heads add only manager merges of origin/dev keeping every test-layout registration. Exact-head PR CI run 40174458270 and exact-head ci.yml lane=all run 40174460698 both succeeded at 71b9fb0. Linux real-machine verification at the earlier head 6d79ad1 also passed with full coverage. Static merge simulation on current dev 50afcec (this Mac): dev=50afcec56514992944d890e6577f709eb7075cad base=50afcec56514992944d890e6577f709eb7075cad pr_files= 34 overlap=[]; merge clean; install exit=0; gui install exit=0; tsc exit=0; tsc doctor exit=0; gui tsc -b exit=0; gui lint exit=0; structure:check exit=0; privacy:scan exit=0; layout+ratchet guards exit=0 54 pass 0 fail ; Merged by the triage manager as maintainer integration (MAINTAINERS.md, dev only) with green exact-head PR CI, an independent review PASS, and the owner's approval of this bundle. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ 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. |
Summary
Hermes keeps a separate home for each bot profile: the default profile is
HERMES_HOME/%LOCALAPPDATA%\hermes/~/.hermes, and each named profile is<root>/profiles/<name>/config.yaml, run withHERMES_HOMEpointed at it. Connect → Hermes only ever wrote the default profile, so other bots never received the OpenCodex provider or model catalog (#7674).hermes_constants.pyat 4dcef215:PROFILE_ID_RE, identity markers,profiles/.deletedtombstones,_hermes_root_ofroot derivation, Windows%LOCALAPPDATA%\hermes); links and junctions are never listed. Docs: https://hermes-agent.nousresearch.com/docs/user-guide/profilesprofile=<name>on/api/client-integrations/hermes,client=hermes&profile=<name>on preview/journal/restore;GET /api/client-integrations/hermes/profileslists every profile with its own state. No selector (orprofile=default) behaves exactly as before.integrations/hermes-profiles/<name>/(records, journal, snapshots), so apply, disable, replace, undo and history deletion stay inside that profile. Onlyproviders.opencodexis written; each profile keeps itsmodel.defaultand other providers.guard(restore now honors it too) re-check the pinned profile directories, link/junction refusal, tombstones and the owner record path before any disk access, so a same-named profile under another Hermes home cannot take over ownership. Uninstall pins and guards every owned profile.docs-siteintegrations guide section; newstructure/clients/hermes.md(structure/clients/integrations.mdnet 0 lines).Out of scope: CLI profile flags, an "apply to all profiles" batch action, translated docs pages, aggregating named-profile rows into the unscoped journal. Hermes has no automatic catalog refresh today (default included), so profiles match that.
Closes #7674
Verification
Final head
d3718f787cf9c33af24cff8d1d7e7cc52943f131(includesorigin/dev26598df2c), Windows 11, Bun 1.4.3 test runner.0aeaf0cb6):bun test tests/clients/hermes-profile-routes.test.ts→ 0 pass / 8 fail (every profile-scoped request answered 400).bun test tests/clients/hermes-profile-routes.test.ts tests/clients/hermes-profiles.test.ts tests/test-layout-tooling.test.ts tests/test-layout.test.ts tests/server/management-integration-routes.test.ts tests/cli/uninstall.test.ts tests/cli/cli-integration-preview.test.ts→ 312 pass / 0 fail.bun run typecheck,bun run structure:check,bun run privacy:scan,bun run lint:gui→ exit 0. GUI tests (cd gui && bun run test) → 3515 pass / 0 fail. GUItsc -bexit 0. docs-siteastro buildexit 0 (593 pages, internal links checked).bun run test:changed→ exit 124 on this host. The failures areEICACLS(icacls) insideatomicWriteFileunder the parallel isolate runner and affect Claude Desktop, native-main, Aside and Hermes write tests alike. The same runner on cleanorigin/dev26598df2cfails the same way (bun run test tests/server/management-integration-routes.test.ts tests/cli/uninstall.test.ts tests/codex-integration/native-profile-startup.test.ts→ 166 pass / 38 fail), and those files pass when run directly here (above). Treated as a pre-existing host environment failure; coverage left to CI.3c21fd4b3PASS (one low GUI finding, fixed indf90448a4); delta re-review atdf90448a4PASS, 0 findings.react-doctor@0.9.11 gui --scope changed --blocking warning→ no issues (the profile list usesul/lisincea70741830); GUI tests rerun at that head → 3515 pass / 0 fail.a70741830caught a real regression:tests/clients/integrations-writer-guard.test.ts"restore keeps its existing contract" (restore must ignore the background-refreshguard). Fixed ind3718f787with a separaterestoreGuardhook for the Hermes boundary; that file plus Hermes, management-route, uninstall and Aside suites → 266 pass / 0 fail. Remaining direct-run failures on this host (claude-messages-endpoint: 3 tests) reproduce identically on cleanorigin/dev26598df2c.ci.ymlworkflow_dispatchlane=allon the exact head: https://github.com/lidge-jun/opencodex/actions/runs/40143539223bun run test(shared Windows host; the per-user test lock is contended by other lanes and the runner hits theEICACLSenvironment failure above).Checklist