atbash-hermes-plugin 0.4.10.dev1__py3-none-any.whl → 0.4.10.dev2__py3-none-any.whl

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.
@@ -676,6 +676,22 @@ def _extract_allow(raw: Any) -> Optional[bool]:
676
676
  return None
677
677
 
678
678
 
679
+ def _extract_status(raw: Any) -> str:
680
+ """Read the judge's server-reported `status`, lower-cased ("" when absent).
681
+
682
+ `"logged"` is the ONLY signal that a missing verdict is the AUDIT tier
683
+ choosing not to enforce, rather than a degraded or hostile response.
684
+ """
685
+ status_attr = getattr(raw, "status", None)
686
+ if isinstance(status_attr, str):
687
+ return status_attr.strip().lower()
688
+ if isinstance(raw, dict):
689
+ v = raw.get("status")
690
+ if isinstance(v, str):
691
+ return v.strip().lower()
692
+ return ""
693
+
694
+
679
695
  def _extract_reason(raw: Any) -> str:
680
696
  reason_attr = getattr(raw, "reason", None)
681
697
  if reason_attr is None:
@@ -1055,10 +1071,32 @@ class AtbashHermesGuard:
1055
1071
  }
1056
1072
 
1057
1073
  if verdict == "NO VERDICT":
1058
- # AUDIT-tier organisations receive "No verdict" (log-only mode).
1059
- # Treat as ALLOW — do not block, update baseline.
1060
- self._snapshots[path] = new_content
1061
- self._hash_store.set(path, _sha256_hex(new_content))
1074
+ # AUDIT-tier organisations receive "No verdict" (log-only mode)
1075
+ # and the server says so explicitly with status "logged". Every
1076
+ # other way a verdict goes missing — empty body, truncated
1077
+ # payload, a proxy error page served as 200, a buggy or
1078
+ # compromised judge — normalises to "No verdict" too. Allowing
1079
+ # those would let a poisoning payload through exactly when the
1080
+ # judge is least trustworthy AND make it the new tamper
1081
+ # baseline. Same rule as the SDK's audit_tool_call.
1082
+ status = _extract_status(verdict_raw)
1083
+ if status == "logged":
1084
+ self._snapshots[path] = new_content
1085
+ self._hash_store.set(path, _sha256_hex(new_content))
1086
+ return None
1087
+ logger.warning(
1088
+ "Atbash memory write no verdict without audit marker path=%s status=%s reason=%s",
1089
+ path, status or "absent", reason,
1090
+ )
1091
+ if self.fail_closed:
1092
+ return {
1093
+ "action": "block",
1094
+ "message": (
1095
+ "Memory write blocked (judge returned no verdict without an "
1096
+ f"audit-tier marker; status: {status or 'absent'}): {reason}"
1097
+ ),
1098
+ }
1099
+ # fail-open: allow but do NOT advance baseline — content was not judged.
1062
1100
  return None
1063
1101
 
1064
1102
  if verdict == "ERROR":
@@ -1088,9 +1126,8 @@ class AtbashHermesGuard:
1088
1126
  f"Memory write blocked (unrecognized verdict {verdict!r}): {reason}"
1089
1127
  ),
1090
1128
  }
1091
- # fail-open: accept the write, update baseline
1092
- self._snapshots[path] = new_content
1093
- self._hash_store.set(path, _sha256_hex(new_content))
1129
+ # fail-open: allow but do NOT advance baseline — an unrecognised
1130
+ # verdict did not judge the content, same as ERROR / unmarked NO VERDICT.
1094
1131
  return None
1095
1132
 
1096
1133
  except Exception as e:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atbash-hermes-plugin
3
- Version: 0.4.10.dev1
3
+ Version: 0.4.10.dev2
4
4
  Summary: Atbash safety plugin for Hermes Agent
5
5
  Author: atbash
6
6
  License-Expression: LicenseRef-Atbash-Proprietary
@@ -242,6 +242,12 @@ Hermes sessions.
242
242
  - Atbash API error:
243
243
  - `ATBASH_ENFORCE_DECISION=true`: fail closed and block.
244
244
  - `ATBASH_ENFORCE_DECISION=false`: fail open and allow.
245
+ - Memory writes (`MEMORY.md`, `CLAUDE.md`, `memory/` paths) with `No verdict`: allowed
246
+ and recorded as the new tamper baseline only when the judge marks the response as the
247
+ AUDIT tier (`status: "logged"`). Any other missing verdict — empty body, truncated
248
+ payload, a proxy error served as 200, a compromised judge — is blocked under
249
+ `ATBASH_ENFORCE_DECISION=true`; under `false` the write proceeds but is never
250
+ recorded as the baseline, because it was not judged.
245
251
 
246
252
  Atbash ships fail-closed on every tier. Setting `ATBASH_ENFORCE_DECISION=false`
247
253
  inverts that for this agent: a judge outage becomes a silent allow, and the
@@ -0,0 +1,7 @@
1
+ atbash_hermes_plugin/__init__.py,sha256=M8cKJulLKG1q0bN15eTKH-27oH6y9JJIe9Ue5rUl7HM,55112
2
+ atbash_hermes_plugin-0.4.10.dev2.dist-info/licenses/LICENSE,sha256=1vOJDJvAuOLDHJ8-Q0qDdOXZJJVli6Lr9mKKaFsOa5w,1600
3
+ atbash_hermes_plugin-0.4.10.dev2.dist-info/METADATA,sha256=-Z4S-cH45jATOquRsGhxQAHWSVdbQcGMpCY_CBcVHsg,8547
4
+ atbash_hermes_plugin-0.4.10.dev2.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
5
+ atbash_hermes_plugin-0.4.10.dev2.dist-info/entry_points.txt,sha256=YezkmasjRBXrSlXpqhSJdFhDCdBbENp-_THYtkcRTBo,67
6
+ atbash_hermes_plugin-0.4.10.dev2.dist-info/top_level.txt,sha256=0nT35m8jNxzbQB3CerGf5kgH7hm_pc6GLadlf69w_JM,21
7
+ atbash_hermes_plugin-0.4.10.dev2.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- atbash_hermes_plugin/__init__.py,sha256=vd7kxSnqMGrU3oYttRM6bLw5WwU4Rg5UsDXFXtO0pt8,53307
2
- atbash_hermes_plugin-0.4.10.dev1.dist-info/licenses/LICENSE,sha256=1vOJDJvAuOLDHJ8-Q0qDdOXZJJVli6Lr9mKKaFsOa5w,1600
3
- atbash_hermes_plugin-0.4.10.dev1.dist-info/METADATA,sha256=Hc4ffzsDOASmiNASYWQ38KvfB4wt6Q4zENxAOqO3qbY,8069
4
- atbash_hermes_plugin-0.4.10.dev1.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
5
- atbash_hermes_plugin-0.4.10.dev1.dist-info/entry_points.txt,sha256=YezkmasjRBXrSlXpqhSJdFhDCdBbENp-_THYtkcRTBo,67
6
- atbash_hermes_plugin-0.4.10.dev1.dist-info/top_level.txt,sha256=0nT35m8jNxzbQB3CerGf5kgH7hm_pc6GLadlf69w_JM,21
7
- atbash_hermes_plugin-0.4.10.dev1.dist-info/RECORD,,