#!/usr/bin/env python3 """Check local homelab AI memory provenance and freshness.""" from __future__ import annotations import argparse import json import os from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] DEFAULT_INDEX_DIR = Path(os.environ.get("LAB_AI_KNOWLEDGE_INDEX_DIR", "/data/homelab-ai/index")) def check(index_dir: Path) -> int: manifest_path = index_dir / "manifest.json" if not manifest_path.is_file(): print(f"fail index manifest missing: {manifest_path}") print("fix: ./jeannie ai-index") return 1 manifest = json.loads(manifest_path.read_text(encoding="utf-8")) stale: list[str] = [] missing: list[str] = [] for rel_path, indexed_mtime in manifest.get("files", {}).items(): path = REPO_ROOT / rel_path if not path.is_file(): missing.append(rel_path) continue if int(path.stat().st_mtime) > int(indexed_mtime): stale.append(rel_path) print("Jeannie Memory") print("==============") print(f"index: {index_dir}") print(f"chunks: {manifest.get('chunk_count', 'unknown')}") print(f"sources: {manifest.get('file_count', 'unknown')}") if stale: print(f"status: stale ({len(stale)} source file(s) changed)") for rel_path in stale[:20]: print(f" stale: {rel_path}") print("fix: ./jeannie ai-index") return 1 if missing: print(f"status: warn ({len(missing)} indexed source file(s) missing)") for rel_path in missing[:20]: print(f" missing: {rel_path}") print("fix: ./jeannie ai-index") return 1 print("status: ok") return 0 def main() -> int: parser = argparse.ArgumentParser(description=__doc__) subparsers = parser.add_subparsers(dest="command", required=True) check_parser = subparsers.add_parser("check") check_parser.add_argument("--index-dir", type=Path, default=DEFAULT_INDEX_DIR) args = parser.parse_args() if args.command == "check": return check(args.index_dir) return 2 if __name__ == "__main__": raise SystemExit(main())