Open a private security advisory, or a regular issue if the problem is not sensitive. There is no bounty; this is a free tool.
Stated plainly so you can decide whether that is acceptable before installing.
Reads:
<hermes home>/state.db— your session store, alwaysmode=ro. Message content, roles, timestamps, and thesessionsrow for the session being measured. This is the transcript of your work, including anything you pasted into a chat.<hermes home>/config.yaml— onlycompression.*,model.context_length,model.base_url, andplugins.enabled. Nothing else is inspected, logged, or transmitted. Secrets do not live in this file (Hermes keeps them in.env) and no value from it is printed except the ones named in the report.<hermes home>/context_length_cache.yaml— the context window Hermes measured for your endpoint.<hermes home>/runtime/session-weight-watch.json— this tool's own state.
Writes:
<hermes home>/skills/productivity/long-session-handoff/and<hermes home>/plugins/session-weight-watch/— the tool itself, at install.<hermes home>/runtime/session-weight-watch.json— anti-nag state and the learned token overhead.<hermes home>/handoffs/— session exports andchains.json, when you accept a handoff.config.yaml— one entry inplugins.enabled, written throughhermes config set. If the launcher is unavailable the file is backed up first, and if it already has aplugins:block the installer refuses to edit it blind and prints the line for you to add.sessions.title,sessions.model,sessions.model_config,sessions.end_reason/ended_at, and onesession_turn_leasesdelete — only for the continuation session thathandoff.pyjust created, and only during a handoff you asked for. The parent's rows are never modified except for the watcher-suppression entry, which lives outside the database.
Sends over the network: nothing. There is no telemetry, no update check, and
no outbound request of any kind. The only process it launches is your own
hermes binary, locally.
Your transcripts contain whatever you have discussed with the model, which may include credentials pasted into a session. Two consequences:
- Exports under
<hermes home>/handoffs/are as sensitive as the transcripts they came from. They are plain files with your umask's default permissions. Do not commit them, and delete directories you no longer need — nothing here prunes them for you, and--uninstalldeliberately leaves them alone because they are your data. --jsonand the--explainreport are safe to share. They contain counts, token numbers, model and provider names, setting names, and a session title. They contain no message content. Files underhandoffs/are not safe to share.
If a handoff export must live inside a git repository (so it survives a reboot
alongside the project), add it to .gitignore unless you have read it and know
what is in it.
-
The session store is treated as data, never as instructions. The scorer counts typed columns and measures lengths. The exporter copies content into files without interpreting it. Nothing in a transcript can change what these scripts do.
The one place transcript content reaches a model is the export itself, which the continuation reads — that is the entire purpose. The seeding prompt states plainly that the files are a record to read, not instructions to execute, and forbids starting work in that turn. Treat a transcript containing untrusted pasted content the way you would treat any file you hand a model.
-
Compaction is counted structurally, never by string search. Partly for accuracy (a substring match scores the agent's own tool output — measured at 35 false rows in one database) and partly because a string search over content you did not write is a weaker foundation than a typed column.
-
The hook input is untrusted. A missing session id, a non-list conversation history, an unparseable state file, a locked database: every path returns
Noneand costs the turn nothing. Covered bytests/test_handoff.py::test_plugin_fails_open. -
No shell interpolation of session data. Subprocesses are invoked with argument lists, never a constructed command string, so a session title or path containing shell metacharacters cannot become a command.
-
The database is opened read-only for every measurement. The only writes are the ones listed above, all through parameterised statements, all against a session id the caller supplied.
-
The continuation is created with your normal Hermes permissions. Nothing here elevates anything or bypasses an approval prompt. Its seeding turn is instructed to read and report only; a continuation that acts unsupervised is what
--taskasks for explicitly, and it is not the default.
python install.py --uninstallRemoves the skill, the plugin, the runtime state, and the plugins.enabled entry.
Your exports under handoffs/ are left in place, and no Hermes compression
setting is ever changed — this tool never modified them, so there is nothing to
restore.
The main branch. This is a single-maintainer project with no backport policy;
fixes land on main and are tagged.