#!/usr/bin/env python3 """Check Cortex as its intended user. Optional isolated offline initializer test.""" import argparse import json import os from pathlib import Path import subprocess import sys import tempfile from install import guard, payload, check_target, state_directory def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--root", type=Path, required=True) parser.add_argument("--scope", choices=["home", "project"], required=True) parser.add_argument("--exercise-project-init", action="store_true", help="Home scope only: test bundled CLI in a private temporary fixture") args = parser.parse_args() if os.name != "posix" or os.geteuid() == 0: parser.error("Verify as the intended non-root user without application sudo") root = args.root.expanduser() check_target(root, args.scope) files = payload(args.scope, root) checks = {} for name in files: path = root / name guard(path) checks["file:" + name] = path.is_file() and os.access(path, os.R_OK | os.W_OK) if name != "AGENTS.md" and path.is_file(): checks["private:" + name] = not path.stat().st_mode & 0o077 agents = root / "AGENTS.md" text = agents.read_text() if agents.is_file() else "" checks["agent_reading_route"] = all(name in text for name in [".ai/START.md", ".ai/NOW.md", ".ai/protocols/operate.md"]) for name in [".ai/START.md", ".ai/NOW.md", ".ai/protocols/operate.md", ".ai/protocols/bootstrap.md"]: checks["nonempty:" + name] = (root / name).is_file() and bool((root / name).read_text().strip()) if args.exercise_project_init: if args.scope != "home": parser.error("--exercise-project-init requires home scope") os.umask(0o077) scratch = state_directory().parent / "verification" guard(scratch) scratch.mkdir(parents=True, mode=0o700, exist_ok=True) with tempfile.TemporaryDirectory(prefix="offline-project-", dir=scratch) as directory: project = Path(directory) / "sample-project" project.mkdir(mode=0o700) sentinel = project / "app.txt" sentinel.write_text("Owner application fixture: preserve me\n") command = [sys.executable, str(root / ".ai/tools/project-cortex/cortex.py"), "init", str(project)] subprocess.run(command + ["--dry-run"], check=True, capture_output=True, timeout=20) checks["project_preview_no_write"] = not (project / ".ai").exists() subprocess.run(command, check=True, capture_output=True, timeout=20) installed = (project / "AGENTS.md").read_text() + "\nOwner fixture edit\n" (project / "AGENTS.md").write_text(installed) subprocess.run(command, check=True, capture_output=True, timeout=20) checks["project_init_and_preservation"] = (project / ".ai/START.md").is_file() and (project / "AGENTS.md").read_text() == installed and sentinel.read_text() == "Owner application fixture: preserve me\n" result = {"root": str(root), "scope": args.scope, "checks": checks, "passed": all(checks.values()), "native_agent_loading_verified": False, "note": "Files and reading route checked; ask the existing agent to read AGENTS/START/NOW. No runner, model, memory daemon or automatic synchronization is implied."} print(json.dumps(result, indent=2)) return 0 if result["passed"] else 1 if __name__ == "__main__": sys.exit(main())