#!/usr/bin/env python3 """ Audit the fleet shared palace for privacy violations. Ensures no raw drawers, full source paths, or private workspace leaks exist. Usage: python audit_mempalace_privacy.py /path/to/fleet/palace Exit codes: 0 = clean 1 = violations found """ import sys from pathlib import Path try: import chromadb except ImportError: print("ERROR: chromadb not installed") sys.exit(1) VIOLATION_KEYWORDS = [ "/root/wizards/", "/home/", "/Users/", "private_key", "-----BEGIN", "GITEA_TOKEN=", "OPENAI_API_KEY", "ANTHROPIC_API_KEY", ] def audit(palace_path: Path): violations = [] client = chromadb.PersistentClient(path=str(palace_path)) try: col = client.get_collection("mempalace_drawers") except Exception as e: print(f"ERROR: Could not open collection: {e}") sys.exit(1) all_data = col.get(include=["documents", "metadatas"]) docs = all_data["documents"] metas = all_data["metadatas"] for doc, meta in zip(docs, metas): source = meta.get("source_file", "") doc_type = meta.get("type", "") # Rule 1: Fleet palace should only contain closets or explicitly typed entries if doc_type not in ("closet", "summary", "fleet"): violations.append( f"VIOLATION: Document type is '{doc_type}' (expected closet/summary/fleet). " f"Source: {source}" ) # Rule 2: No full absolute paths from private workspaces if any(abs_path in source for abs_path in ["/root/wizards/", "/home/", "/Users/"]): violations.append( f"VIOLATION: Source contains absolute path: {source}" ) # Rule 3: No raw secrets in document text for kw in VIOLATION_KEYWORDS: if kw in doc: violations.append( f"VIOLATION: Document contains sensitive keyword '{kw}'. Source: {source}" ) break # one violation per doc is enough return violations def main(): import argparse parser = argparse.ArgumentParser(description="Audit fleet palace privacy") parser.add_argument("palace", default="/var/lib/mempalace/fleet", nargs="?", help="Path to fleet palace") args = parser.parse_args() violations = audit(Path(args.palace)) if violations: print(f"FAIL: {len(violations)} privacy violation(s) found") for v in violations: print(f" {v}") sys.exit(1) else: print("PASS: No privacy violations detected") sys.exit(0) if __name__ == "__main__": main()