#!/usr/bin/env python3 """Run deterministic repository integrity checks without external services.""" from __future__ import annotations import ast import json from collections import Counter from pathlib import Path ROOT = Path(__file__).resolve().parents[1] COLLECTIONS = ("jobs", "papers", "industry") REQUIRED_FILES = ( "AGENTS.md", "README.md", "docs/06-project-status.md", "docs/07-exploration-history.md", "docs/08-next-work.md", "data/index.json", "data/summary.json", "research/memory/findings.md", "research/memory/evidence-ledger.md", "research/evaluation/k1412-agent-evaluation-v1.md", "data/evaluation/k1412-agent-eval-task-contracts-v1.json", "tools/evaluation/score_agent_runs.py", "evaluation-site/index.html", "evaluation-site/assets/styles.css", "evaluation-site/assets/app.js", "evaluation-site/Dockerfile", "evaluation-site/nginx.conf", "web/app.py", "web/agent-knowledge-atlas.service", "web/manage.sh", ) def load_json(path: str): return json.loads((ROOT / path).read_text(encoding="utf-8")) def require(condition: bool, message: str) -> None: if not condition: raise AssertionError(message) def check_required_files() -> None: missing = [path for path in REQUIRED_FILES if not (ROOT / path).is_file()] require(not missing, f"missing required files: {', '.join(missing)}") def check_collection_index() -> dict[str, int]: index = load_json("data/index.json") summary = load_json("data/summary.json") require(isinstance(index, list), "data/index.json must be an array") paths = [str(item.get("path") or "") for item in index] require(len(paths) == len(set(paths)), "data/index.json contains duplicate paths") missing_paths = [path for path in paths if not (ROOT / path).is_file()] require(not missing_paths, f"index points to missing files: {missing_paths[:5]}") indexed = Counter(str(item.get("collection") or "") for item in index) filesystem = { collection: sum( 1 for path in (ROOT / collection / "items").glob("*.md") if path.name != "README.md" ) for collection in COLLECTIONS } require(dict(indexed) == filesystem, f"index/file count mismatch: {dict(indexed)} != {filesystem}") require(summary.get("total") == len(index), "summary total does not match index") require(summary.get("by_collection") == filesystem, "summary collection counts are stale") return filesystem def check_research_data() -> dict[str, int]: expanded = load_json("data/research/agent-memory-expanded.json") screened = load_json("data/research/agent-memory-screened.json") landscape = load_json("data/research/memory-landscape.json") corpus = load_json("data/research/memory-corpus.json") candidate_count = len(expanded.get("papers", [])) require(expanded.get("unique_papers") == candidate_count, "expanded memory count mismatch") require(screened.get("total") == candidate_count, "screen total mismatch") require(screened.get("completed") == candidate_count, "memory screening is incomplete") require(len(screened.get("papers", [])) == candidate_count, "screen paper count mismatch") require(landscape.get("source_candidates") == candidate_count, "landscape source count mismatch") require(corpus.get("resolved") == len(corpus.get("papers", [])), "local memory corpus mismatch") return { "memory_candidates": candidate_count, "memory_title_central": int(landscape.get("title_central") or 0), "memory_local_topic": int(corpus.get("resolved") or 0), } def check_python_syntax() -> int: paths = sorted((ROOT / "tools").rglob("*.py")) + [ROOT / "web" / "app.py"] for path in paths: ast.parse(path.read_text(encoding="utf-8"), filename=str(path)) return len(paths) def check_ollama_contract() -> None: source = (ROOT / "web" / "app.py").read_text(encoding="utf-8") require('"num_ctx"' not in source, "web app must not override Ollama num_ctx") require('"keep_alive"' not in source, "web app must not override Ollama keep_alive") def check_experiment_state() -> None: module = load_json("learning/agent-memory/module.json") require(module.get("status") == "failed", "old learning pilot must remain marked failed") pilot = (ROOT / "experiments/knowledge-compilation/2026-07-10-agent-memory-pilot.md").read_text( encoding="utf-8" ) require("status: failed" in pilot, "pilot experiment status is stale") def check_evaluation_contract() -> int: suite = load_json("data/evaluation/k1412-agent-eval-task-contracts-v1.json") require( suite.get("schema_version") == "agent-eval-task-contracts/v1", "unknown Agent evaluation task schema", ) tasks = suite.get("tasks") require(isinstance(tasks, list) and tasks, "Agent evaluation task suite is empty") budget_profiles = suite.get("budget_profiles") or {} require(isinstance(budget_profiles, dict) and budget_profiles, "evaluation budget profiles are empty") task_ids = [str(task.get("task_id") or "") for task in tasks] require(all(task_ids), "Agent evaluation task is missing task_id") require(len(task_ids) == len(set(task_ids)), "Agent evaluation task ids are not unique") for task in tasks: require(task.get("title_zh"), f"{task['task_id']} is missing Chinese title") require(task.get("version"), f"{task['task_id']} is missing version") require(task.get("runner_status"), f"{task['task_id']} is missing runner_status") require( task.get("budget_profile") in budget_profiles, f"{task['task_id']} references an unknown budget profile", ) require(task.get("observable_completion"), f"{task['task_id']} has no completion contract") require(task.get("forbidden_effects") is not None, f"{task['task_id']} has no forbidden effects") return len(tasks) def check_evaluation_site() -> None: html = (ROOT / "evaluation-site/index.html").read_text(encoding="utf-8") javascript = (ROOT / "evaluation-site/assets/app.js").read_text(encoding="utf-8") dockerfile = (ROOT / "evaluation-site/Dockerfile").read_text(encoding="utf-8") nginx = (ROOT / "evaluation-site/nginx.conf").read_text(encoding="utf-8") require("不是真实跑分" in html, "evaluation simulation must keep its evidence boundary visible") require("尚未运行真实模型对比" in html, "evaluation report overstates current evidence") require("const TASKS" in javascript, "evaluation task browser is missing") require("install -d -m 0755" in dockerfile, "static asset directory must remain traversable") require('location = /health' in nginx, "evaluation site health endpoint is missing") def main() -> int: check_required_files() collections = check_collection_index() research = check_research_data() python_files = check_python_syntax() check_ollama_contract() check_experiment_state() evaluation_tasks = check_evaluation_contract() check_evaluation_site() print( json.dumps( { "ok": True, "collections": collections, "research": research, "evaluation_tasks": evaluation_tasks, "evaluation_site": True, "python_files_checked": python_files, }, ensure_ascii=False, indent=2, ) ) return 0 if __name__ == "__main__": raise SystemExit(main())