audit: phase 0 tooling for file-by-file 40250 porting

- refroot.py: one reference-root resolver (MT_40250_SOURCE, then manifest)
  used by every audit script; missing tree or fingerprint input is an error
- port_map.py: per-function inventory of active 40250 units plus the
  40250 Python root, status/queue/init/show/check, 40250: tag scan
- manifest: fix 18 wrong reference paths (Python UI now points at the
  40250 Client/Eternexus/root, not the m2dev assets/root), drop 2 deleted
  implementation files, move 64 prose test entries to evidence.commands
- first port-map entry: PythonPlayerEventHandler.cpp
- roadmap replaced by a batch/unit queue

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-22 17:17:49 +09:00
co-authored by Claude Opus 5
parent 6a175ee293
commit 55f733fda6
16 changed files with 621 additions and 468 deletions
@@ -11,6 +11,8 @@ from collections import Counter
from datetime import datetime, timezone
from pathlib import Path
import refroot # script directory is on sys.path when run directly
STATUSES = {
"UNMAPPED", "PARTIAL", "MAPPED", "STATIC_VERIFIED", "TEST_VERIFIED",
@@ -67,8 +69,7 @@ def resolve_files(root: Path, data: dict, section: str) -> list[Path]:
files = contract.get(section, {}).get("files", []) if section != "tests" else contract.get("evidence", {}).get("tests", [])
base = root
if section == "reference":
ref_root = Path(data.get("_reference_root", ""))
base = ref_root if ref_root.is_absolute() else root / ref_root
base = refroot.reference_root(root)
return [(base / item).resolve() for item in files]
@@ -77,8 +78,7 @@ def fingerprint(paths: list[Path]) -> str:
for path in sorted(paths, key=lambda p: str(p)):
digest.update(str(path).encode())
if not path.is_file():
digest.update(b"<missing>")
continue
raise SystemExit(f"fingerprint input missing: {path}")
digest.update(hashlib.sha256(path.read_bytes()).digest())
return digest.hexdigest()
@@ -218,9 +218,8 @@ def command_next(_root: Path, manifest: dict, args: argparse.Namespace) -> int:
def command_refresh(root: Path, manifest: dict, args: argparse.Namespace) -> int:
changed = 0
ref_root = manifest.get("reference_root", "")
for contract in manifest["contracts"]:
working = {**contract, "_reference_root": ref_root}
working = contract
current = {
"reference": fingerprint(resolve_files(root, working, "reference")),
"implementation": fingerprint(resolve_files(root, working, "implementation")),