Files
the-nexus/tests/test_mempalace_audit_privacy.py
Claude (Opus 4.6) e957254b65
Some checks failed
Deploy Nexus / deploy (push) Has been cancelled
[claude] MemPalace × Evennia fleet memory scaffold (#1075) (#1088)
2026-04-07 14:12:38 +00:00

130 lines
4.1 KiB
Python

"""
Tests for mempalace/audit_privacy.py — fleet palace privacy auditor.
Refs: #1083, #1075
"""
import json
from pathlib import Path
import pytest
from mempalace.audit_privacy import (
Violation,
audit_file,
audit_palace,
_is_private_path,
)
# ---------------------------------------------------------------------------
# _is_private_path
# ---------------------------------------------------------------------------
def test_private_path_root():
assert _is_private_path("/root/wizards/bezalel/workspace.md") is True
def test_private_path_home():
assert _is_private_path("/home/apayne/projects/nexus") is True
def test_private_path_users():
assert _is_private_path("/Users/apayne/worktrees/nexus/foo.py") is True
def test_non_private_path():
assert _is_private_path("/var/lib/mempalace/fleet/bezalel/forge.closet.json") is False
assert _is_private_path("relative/path.md") is False
# ---------------------------------------------------------------------------
# audit_file — clean closet
# ---------------------------------------------------------------------------
def _write_closet(tmp_path: Path, name: str, drawers: list) -> Path:
p = tmp_path / name
p.write_text(json.dumps({"drawers": drawers}))
return p
def test_clean_closet_has_no_violations(tmp_path):
f = _write_closet(tmp_path, "forge.closet.json", [
{"text": "Build succeeded on commit abc123.", "closet": True},
])
assert audit_file(f) == []
# ---------------------------------------------------------------------------
# audit_file — raw drawer violation
# ---------------------------------------------------------------------------
def test_raw_drawer_file_is_violation(tmp_path):
f = tmp_path / "workspace.drawer.json"
f.write_text(json.dumps({"text": "some private content"}))
violations = audit_file(f)
assert len(violations) == 1
assert violations[0].rule == "RAW_DRAWER"
# ---------------------------------------------------------------------------
# audit_file — full text in closet
# ---------------------------------------------------------------------------
def test_full_text_closet_is_violation(tmp_path):
long_text = "x" * 3000 # exceeds 2000 char limit
f = _write_closet(tmp_path, "nexus.closet.json", [
{"text": long_text, "closet": True},
])
violations = audit_file(f)
assert any(v.rule == "FULL_TEXT_IN_CLOSET" for v in violations)
# ---------------------------------------------------------------------------
# audit_file — private source_file path
# ---------------------------------------------------------------------------
def test_private_source_file_is_violation(tmp_path):
f = _write_closet(tmp_path, "hermes.closet.json", [
{
"text": "Short summary.",
"source_file": "/root/wizards/bezalel/secret.md",
"closet": True,
}
])
violations = audit_file(f)
assert any(v.rule == "PRIVATE_SOURCE_PATH" for v in violations)
def test_fleet_source_file_is_ok(tmp_path):
f = _write_closet(tmp_path, "hermes.closet.json", [
{
"text": "Short summary.",
"source_file": "/var/lib/mempalace/fleet/bezalel/hermes.closet.json",
"closet": True,
}
])
violations = audit_file(f)
assert violations == []
# ---------------------------------------------------------------------------
# audit_palace
# ---------------------------------------------------------------------------
def test_audit_palace_clean(tmp_path):
_write_closet(tmp_path, "forge.closet.json", [{"text": "ok", "closet": True}])
_write_closet(tmp_path, "nexus.closet.json", [{"text": "ok", "closet": True}])
result = audit_palace(tmp_path)
assert result.clean
assert result.scanned == 2
def test_audit_palace_finds_violations(tmp_path):
_write_closet(tmp_path, "forge.closet.json", [{"text": "ok", "closet": True}])
bad = tmp_path / "secret.drawer.json"
bad.write_text(json.dumps({"text": "raw private data"}))
result = audit_palace(tmp_path)
assert not result.clean
assert any(v.rule == "RAW_DRAWER" for v in result.violations)