atbash-hermes-plugin 0.9.12.dev0__tar.gz → 0.11.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {atbash_hermes_plugin-0.9.12.dev0/atbash_hermes_plugin.egg-info → atbash_hermes_plugin-0.11.1}/PKG-INFO +67 -5
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/README.md +65 -3
- atbash_hermes_plugin-0.11.1/atbash_hermes_plugin/__init__.py +2911 -0
- atbash_hermes_plugin-0.11.1/atbash_hermes_plugin/__main__.py +49 -0
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1/atbash_hermes_plugin.egg-info}/PKG-INFO +67 -5
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/atbash_hermes_plugin.egg-info/SOURCES.txt +7 -1
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/atbash_hermes_plugin.egg-info/requires.txt +1 -1
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/plugin.yaml +6 -3
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/pyproject.toml +2 -2
- atbash_hermes_plugin-0.11.1/tests/test_guard_selfprotection.py +807 -0
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/tests/test_memory_poisoning.py +24 -5
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/tests/test_memory_write_fail_closed.py +10 -1
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/tests/test_pre_tool_call_verdicts.py +20 -1
- atbash_hermes_plugin-0.11.1/tests/test_zero_bugs_fuzz.py +470 -0
- atbash_hermes_plugin-0.11.1/tests/test_zero_bugs_issues.py +870 -0
- atbash_hermes_plugin-0.11.1/tests/test_zero_bugs_more.py +347 -0
- atbash_hermes_plugin-0.11.1/tests/test_zero_bugs_round.py +448 -0
- atbash_hermes_plugin-0.9.12.dev0/atbash_hermes_plugin/__init__.py +0 -1378
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/LICENSE +0 -0
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/MANIFEST.in +0 -0
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/NOTICE +0 -0
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/atbash_hermes_plugin.egg-info/dependency_links.txt +0 -0
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/atbash_hermes_plugin.egg-info/entry_points.txt +0 -0
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/atbash_hermes_plugin.egg-info/top_level.txt +0 -0
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/setup.cfg +0 -0
- {atbash_hermes_plugin-0.9.12.dev0 → atbash_hermes_plugin-0.11.1}/tests/test_release_contract.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atbash-hermes-plugin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.1
|
|
4
4
|
Summary: Atbash safety plugin for Hermes Agent
|
|
5
5
|
Author: atbash
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -11,7 +11,7 @@ Requires-Python: <3.13,>=3.9
|
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
13
|
License-File: NOTICE
|
|
14
|
-
Requires-Dist: atbash-sdk==0.
|
|
14
|
+
Requires-Dist: atbash-sdk==0.11.0
|
|
15
15
|
Requires-Dist: httpx<1,>=0.27
|
|
16
16
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2,>=1.29
|
|
17
17
|
Requires-Dist: opentelemetry-sdk<2,>=1.29
|
|
@@ -124,8 +124,10 @@ hermes
|
|
|
124
124
|
## Optional Settings
|
|
125
125
|
|
|
126
126
|
```bash
|
|
127
|
-
# Override the Atbash API endpoint.
|
|
128
|
-
|
|
127
|
+
# Override the Atbash API endpoint. Must be a trusted judge host
|
|
128
|
+
# (atbash.ai / www.atbash.ai under the default policy); other hosts need
|
|
129
|
+
# ATBASH_JUDGE_ENDPOINT_POLICY=self-hosted plus ATBASH_JUDGE_VERIFY_PUBKEY.
|
|
130
|
+
ATBASH_ENDPOINT=https://atbash.ai
|
|
129
131
|
|
|
130
132
|
# Set to self-hosted when using your own judge endpoint. Self-hosted judges
|
|
131
133
|
# require ATBASH_JUDGE_VERIFY_PUBKEY so the SDK can verify signed responses.
|
|
@@ -274,7 +276,9 @@ Hermes sessions.
|
|
|
274
276
|
- `ATBASH_ENFORCE_DECISION=false`: fail open and allow.
|
|
275
277
|
- Memory writes (`MEMORY.md`, `CLAUDE.md`, `memory/` paths) with `No verdict`: allowed
|
|
276
278
|
and recorded as the new tamper baseline only when the judge marks the response as the
|
|
277
|
-
AUDIT tier (`status: "logged"`)
|
|
279
|
+
AUDIT tier (`status: "logged"`) **and** the deployment opts in to monitor-only with
|
|
280
|
+
`ATBASH_ALLOW_AUDIT_TIER=1`. Without the opt-in a `logged` answer is refused like any
|
|
281
|
+
other unjudged one. Any other missing verdict — empty body, truncated
|
|
278
282
|
payload, a proxy error served as 200, a compromised judge — is blocked under
|
|
279
283
|
`ATBASH_ENFORCE_DECISION=true`; under `false` the write proceeds but is never
|
|
280
284
|
recorded as the baseline, because it was not judged.
|
|
@@ -299,6 +303,64 @@ After dashboard approval or rejection, the SDK can query held-action status with
|
|
|
299
303
|
the judgment ID. The Hermes plugin blocks the original tool call and asks the
|
|
300
304
|
user to retry after review, rather than automatically re-running the action.
|
|
301
305
|
|
|
306
|
+
## Guard Self-Protection And Memory Baselines
|
|
307
|
+
|
|
308
|
+
- **The guard's own state is not writable by the agent.** Write tools (`write`, `edit`,
|
|
309
|
+
`multiedit`, `write_file`, `create_file`, `patch`, `apply_patch`, `str_replace_editor`,
|
|
310
|
+
`fs_write`, `notebook_edit`, and anything the tool map classes as `filesystem_write`)
|
|
311
|
+
are refused, before judging and in monitor mode too, when they target
|
|
312
|
+
`~/.config/atbash`, the configured tool map, agent key and hash baseline, a dedicated
|
|
313
|
+
key directory (such as `/opt/data/atbash`), the Hermes home's `.env`, `.op.env`,
|
|
314
|
+
`config.yaml` and `SOUL.md` (`~/.hermes`, `$HERMES_HOME`, and `%LOCALAPPDATA%\hermes` on
|
|
315
|
+
Windows), the Hermes install folder's `.env`, or the plugin's install directory. To
|
|
316
|
+
change one of these (for example your persona in `SOUL.md`), edit the file yourself;
|
|
317
|
+
the agent's write is refused even if you approve it inside Hermes. Paths are
|
|
318
|
+
compared by file identity, so hard links and case variants count. Patch tools are also
|
|
319
|
+
refused when their body names one of those paths.
|
|
320
|
+
- **A memory file with no trusted baseline is blocked, and nothing is sent anywhere.**
|
|
321
|
+
A memory file is one of `AGENTS.md`, `AGENTS.override.md`, `CLAUDE.md`, `MEMORY.md`,
|
|
322
|
+
`USER.md`, `DREAMS.md`, `.hermes.md`, `HERMES.md`, `.cursorrules` (by exact name, and on
|
|
323
|
+
Windows also the spellings Windows opens as that file, such as `AGENTS.md.`), a
|
|
324
|
+
`.cursor/rules/*.mdc` file, a `.md`/`.txt` document inside a `memory/` or `memories/`
|
|
325
|
+
folder, or a file under `~/.claude/projects/` or `~/.openclaw/{workspace,memory}/`.
|
|
326
|
+
Ordinary code such as `src/memory/alloc.rs` is not memory and is judged like any other
|
|
327
|
+
file.
|
|
328
|
+
Files the guard records itself (judged writes) are trusted. For files that existed
|
|
329
|
+
before the guard (a repository's `AGENTS.md`), review them and trust them yourself,
|
|
330
|
+
outside the agent:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
python -m atbash_hermes_plugin seed AGENTS.md memory/notes.md
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Run it from outside the repository you are trusting, with absolute paths (for example
|
|
337
|
+
`cd ~ && python -m atbash_hermes_plugin seed /path/to/repo/AGENTS.md`): `python -m`
|
|
338
|
+
puts the current folder first on Python's import path, so a hostile repository could
|
|
339
|
+
otherwise shadow a standard module. The command itself never imports Hermes code.
|
|
340
|
+
|
|
341
|
+
It prints the baseline file it wrote. That is the one the guard reads:
|
|
342
|
+
`ATBASH_MEMORY_HASH_PATH` from your environment or from the Hermes home `.env`, else
|
|
343
|
+
`~/.config/atbash/hermes-memory-hashes.json`. Pass `--store <file>` to choose it
|
|
344
|
+
explicitly. If any file in the list cannot be read, nothing is trusted.
|
|
345
|
+
|
|
346
|
+
The guard refuses agent tool calls that look like they run the seeder (the command,
|
|
347
|
+
`seed_memory_baselines`, the baseline file's name, including quoted, variable-split or
|
|
348
|
+
base64-encoded forms). This is best effort - see the known limit below - and it also
|
|
349
|
+
refuses harmless agent calls that merely mention those names (editing these docs, a
|
|
350
|
+
grep for the command).
|
|
351
|
+
|
|
352
|
+
In Docker, point the baseline file at the mounted volume so trust survives restarts,
|
|
353
|
+
e.g. `-e ATBASH_MEMORY_HASH_PATH=/opt/data/atbash/hermes-memory-hashes.json`, and run
|
|
354
|
+
the seed command inside the container.
|
|
355
|
+
- **What the guard sees:** tool calls only. Hermes loads its context files (`AGENTS.md`,
|
|
356
|
+
`.hermes.md`, `SOUL.md`, ...) into a new session's instructions without a tool call, so
|
|
357
|
+
baselines protect the agent's tool reads, and the real control on those files is that
|
|
358
|
+
agent writes to them are scanned and judged.
|
|
359
|
+
- **Known limit:** the baseline file (`~/.config/atbash/hermes-memory-hashes.json`) is
|
|
360
|
+
plain JSON. The guard refuses the agent's file tools on it, but a shell command that
|
|
361
|
+
rewrites a memory file and recomputes its SHA-256 is left to the judge. Closing that
|
|
362
|
+
needs an authenticated baseline (a MAC) or state outside the agent's reach.
|
|
363
|
+
|
|
302
364
|
## Troubleshooting
|
|
303
365
|
|
|
304
366
|
If Hermes does not show the plugin:
|
|
@@ -105,8 +105,10 @@ hermes
|
|
|
105
105
|
## Optional Settings
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
|
-
# Override the Atbash API endpoint.
|
|
109
|
-
|
|
108
|
+
# Override the Atbash API endpoint. Must be a trusted judge host
|
|
109
|
+
# (atbash.ai / www.atbash.ai under the default policy); other hosts need
|
|
110
|
+
# ATBASH_JUDGE_ENDPOINT_POLICY=self-hosted plus ATBASH_JUDGE_VERIFY_PUBKEY.
|
|
111
|
+
ATBASH_ENDPOINT=https://atbash.ai
|
|
110
112
|
|
|
111
113
|
# Set to self-hosted when using your own judge endpoint. Self-hosted judges
|
|
112
114
|
# require ATBASH_JUDGE_VERIFY_PUBKEY so the SDK can verify signed responses.
|
|
@@ -255,7 +257,9 @@ Hermes sessions.
|
|
|
255
257
|
- `ATBASH_ENFORCE_DECISION=false`: fail open and allow.
|
|
256
258
|
- Memory writes (`MEMORY.md`, `CLAUDE.md`, `memory/` paths) with `No verdict`: allowed
|
|
257
259
|
and recorded as the new tamper baseline only when the judge marks the response as the
|
|
258
|
-
AUDIT tier (`status: "logged"`)
|
|
260
|
+
AUDIT tier (`status: "logged"`) **and** the deployment opts in to monitor-only with
|
|
261
|
+
`ATBASH_ALLOW_AUDIT_TIER=1`. Without the opt-in a `logged` answer is refused like any
|
|
262
|
+
other unjudged one. Any other missing verdict — empty body, truncated
|
|
259
263
|
payload, a proxy error served as 200, a compromised judge — is blocked under
|
|
260
264
|
`ATBASH_ENFORCE_DECISION=true`; under `false` the write proceeds but is never
|
|
261
265
|
recorded as the baseline, because it was not judged.
|
|
@@ -280,6 +284,64 @@ After dashboard approval or rejection, the SDK can query held-action status with
|
|
|
280
284
|
the judgment ID. The Hermes plugin blocks the original tool call and asks the
|
|
281
285
|
user to retry after review, rather than automatically re-running the action.
|
|
282
286
|
|
|
287
|
+
## Guard Self-Protection And Memory Baselines
|
|
288
|
+
|
|
289
|
+
- **The guard's own state is not writable by the agent.** Write tools (`write`, `edit`,
|
|
290
|
+
`multiedit`, `write_file`, `create_file`, `patch`, `apply_patch`, `str_replace_editor`,
|
|
291
|
+
`fs_write`, `notebook_edit`, and anything the tool map classes as `filesystem_write`)
|
|
292
|
+
are refused, before judging and in monitor mode too, when they target
|
|
293
|
+
`~/.config/atbash`, the configured tool map, agent key and hash baseline, a dedicated
|
|
294
|
+
key directory (such as `/opt/data/atbash`), the Hermes home's `.env`, `.op.env`,
|
|
295
|
+
`config.yaml` and `SOUL.md` (`~/.hermes`, `$HERMES_HOME`, and `%LOCALAPPDATA%\hermes` on
|
|
296
|
+
Windows), the Hermes install folder's `.env`, or the plugin's install directory. To
|
|
297
|
+
change one of these (for example your persona in `SOUL.md`), edit the file yourself;
|
|
298
|
+
the agent's write is refused even if you approve it inside Hermes. Paths are
|
|
299
|
+
compared by file identity, so hard links and case variants count. Patch tools are also
|
|
300
|
+
refused when their body names one of those paths.
|
|
301
|
+
- **A memory file with no trusted baseline is blocked, and nothing is sent anywhere.**
|
|
302
|
+
A memory file is one of `AGENTS.md`, `AGENTS.override.md`, `CLAUDE.md`, `MEMORY.md`,
|
|
303
|
+
`USER.md`, `DREAMS.md`, `.hermes.md`, `HERMES.md`, `.cursorrules` (by exact name, and on
|
|
304
|
+
Windows also the spellings Windows opens as that file, such as `AGENTS.md.`), a
|
|
305
|
+
`.cursor/rules/*.mdc` file, a `.md`/`.txt` document inside a `memory/` or `memories/`
|
|
306
|
+
folder, or a file under `~/.claude/projects/` or `~/.openclaw/{workspace,memory}/`.
|
|
307
|
+
Ordinary code such as `src/memory/alloc.rs` is not memory and is judged like any other
|
|
308
|
+
file.
|
|
309
|
+
Files the guard records itself (judged writes) are trusted. For files that existed
|
|
310
|
+
before the guard (a repository's `AGENTS.md`), review them and trust them yourself,
|
|
311
|
+
outside the agent:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
python -m atbash_hermes_plugin seed AGENTS.md memory/notes.md
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Run it from outside the repository you are trusting, with absolute paths (for example
|
|
318
|
+
`cd ~ && python -m atbash_hermes_plugin seed /path/to/repo/AGENTS.md`): `python -m`
|
|
319
|
+
puts the current folder first on Python's import path, so a hostile repository could
|
|
320
|
+
otherwise shadow a standard module. The command itself never imports Hermes code.
|
|
321
|
+
|
|
322
|
+
It prints the baseline file it wrote. That is the one the guard reads:
|
|
323
|
+
`ATBASH_MEMORY_HASH_PATH` from your environment or from the Hermes home `.env`, else
|
|
324
|
+
`~/.config/atbash/hermes-memory-hashes.json`. Pass `--store <file>` to choose it
|
|
325
|
+
explicitly. If any file in the list cannot be read, nothing is trusted.
|
|
326
|
+
|
|
327
|
+
The guard refuses agent tool calls that look like they run the seeder (the command,
|
|
328
|
+
`seed_memory_baselines`, the baseline file's name, including quoted, variable-split or
|
|
329
|
+
base64-encoded forms). This is best effort - see the known limit below - and it also
|
|
330
|
+
refuses harmless agent calls that merely mention those names (editing these docs, a
|
|
331
|
+
grep for the command).
|
|
332
|
+
|
|
333
|
+
In Docker, point the baseline file at the mounted volume so trust survives restarts,
|
|
334
|
+
e.g. `-e ATBASH_MEMORY_HASH_PATH=/opt/data/atbash/hermes-memory-hashes.json`, and run
|
|
335
|
+
the seed command inside the container.
|
|
336
|
+
- **What the guard sees:** tool calls only. Hermes loads its context files (`AGENTS.md`,
|
|
337
|
+
`.hermes.md`, `SOUL.md`, ...) into a new session's instructions without a tool call, so
|
|
338
|
+
baselines protect the agent's tool reads, and the real control on those files is that
|
|
339
|
+
agent writes to them are scanned and judged.
|
|
340
|
+
- **Known limit:** the baseline file (`~/.config/atbash/hermes-memory-hashes.json`) is
|
|
341
|
+
plain JSON. The guard refuses the agent's file tools on it, but a shell command that
|
|
342
|
+
rewrites a memory file and recomputes its SHA-256 is left to the judge. Closing that
|
|
343
|
+
needs an authenticated baseline (a MAC) or state outside the agent's reach.
|
|
344
|
+
|
|
283
345
|
## Troubleshooting
|
|
284
346
|
|
|
285
347
|
If Hermes does not show the plugin:
|