Files
troupe-standup/wizard-work/sol/verify_sol_profile_file_class.py

134 lines
5.4 KiB
Python

#!/usr/bin/env python3
"""Independent re-verification for the sol-profile file/dir class artifact.
Checks the artifact against live disk using an independently written
recompute + integrity tests. Exit 0 = correct.
Non-tautology: the recompute table is written separately from the generator,
and the checks include (a) every live entry appears exactly once in the
artifact, and (b) every class label belongs to a known vocabulary.
"""
import json
import os
import stat
import sys
PROFILE = "/root/.hermes/profiles/sol"
ARTIFACT = "/root/troupe-standup/wizard-work/sol/sol-profile-file-class-2026-10-27.json"
# Vocabulary of class labels the artifact may use.
ALLOWED = {
"BACKUP::DIR", "BIN::DIR", "CACHE::DIR", "CACHE_ETAG::FILE", "CHECK_DIR::DIR",
"CONFIG_JSON::FILE", "CONFIG_YAML::FILE", "DIR::UNCLASSIFIED", "DOC::FILE",
"FILE::UNCLASSIFIED", "FORGE::DIR", "HOME_DIR::DIR", "HOOK::DIR", "LOCK::FILE",
"LOG_DIR::DIR", "LSP::DIR", "MEMORY::DIR", "OUTPUT_DIR::DIR", "PAIR_PLAT::DIR",
"PLUGIN_DIR::DIR", "RUNTIME_DIR::DIR", "SCRIPT_PY::FILE", "SKILL_CONTAINER::DIR",
"SKIN::DIR", "STATE_DB::FILE", "VAULT::DIR",
}
def rule_class(name):
"""Independent rule: name-based, no os.stat dependency inside the table."""
if os.path.isdir(os.path.join(PROFILE, name)):
if name == "skills":
return "SKILL_CONTAINER::DIR"
if name in ("lsp", "bin", "forge", "skills", "vault", "memories",
"logs", "skins", "pairing", "platforms", "hooks",
"source-checks", "cache", "backups", "keys", "image_cache",
"audio_cache", "plugins", "plugin-update-checks",
"wizard-outputs", "cron", "sessions", "sandboxes",
"runtime", "workspace", "home"):
return {"lsp": "LSP::DIR", "bin": "BIN::DIR", "forge": "FORGE::DIR",
"skills": "SKILL_CONTAINER::DIR", "vault": "VAULT::DIR",
"memories": "MEMORY::DIR", "logs": "LOG_DIR::DIR",
"skins": "SKIN::DIR", "pairing": "PAIR_PLAT::DIR",
"platforms": "PAIR_PLAT::DIR", "hooks": "HOOK::DIR",
"source-checks": "CHECK_DIR::DIR", "cache": "CACHE::DIR",
"backups": "BACKUP::DIR", "keys": "CACHE::DIR",
"image_cache": "CACHE::DIR", "audio_cache": "CACHE::DIR",
"plugins": "PLUGIN_DIR::DIR", "plugin-update-checks":
"PLUGIN_DIR::DIR", "wizard-outputs": "OUTPUT_DIR::DIR",
"cron": "RUNTIME_DIR::DIR", "sessions": "RUNTIME_DIR::DIR",
"sandboxes": "RUNTIME_DIR::DIR", "runtime": "RUNTIME_DIR::DIR",
"workspace": "RUNTIME_DIR::DIR", "home": "HOME_DIR::DIR"}.get(name, "DIR::UNCLASSIFIED")
return "DIR::UNCLASSIFIED"
# files
if ".db" in name:
return "STATE_DB::FILE"
if name.endswith(".py"):
return "SCRIPT_PY::FILE"
if name.endswith((".sh",)):
return "SCRIPT_SH::FILE"
if name.endswith((".yaml", ".yml")):
return "CONFIG_YAML::FILE"
if name.endswith((".json",)):
return "CONFIG_JSON::FILE"
if name.endswith(".lock"):
return "LOCK::FILE"
if name.endswith(".etag"):
return "CACHE_ETAG::FILE"
if name.endswith((".mp3", ".wav", ".png", ".jpg", ".jpeg")):
return "ARTIFACT::FILE"
if name.endswith(".md"):
return "DOC::FILE"
if name.endswith(".txt"):
return "LOG_TXT::FILE"
return "FILE::UNCLASSIFIED"
def main():
a = json.load(open(ARTIFACT, encoding="utf-8"))
errs = []
disk_names = set(os.listdir(PROFILE))
art_names = [e["name"] for e in a["entries"]]
if len(art_names) != len(set(art_names)):
errs.append("duplicate entry names in artifact")
if set(art_names) != disk_names:
missing = disk_names - set(art_names)
extra = set(art_names) - disk_names
errs.append("name set mismatch; missing=%s extra=%s" % (missing, extra))
recomputed = {}
files = dirs = 0
for name in sorted(disk_names):
p = os.path.join(PROFILE, name)
if os.path.isdir(p):
dirs += 1
recomputed[name] = rule_class(name)
else:
files += 1
recomputed[name] = rule_class(name)
if a.get("files") != files:
errs.append("files count artifact=%s recomputed=%s" % (a.get("files"), files))
if a.get("dirs") != dirs:
errs.append("dirs count artifact=%s recomputed=%s" % (a.get("dirs"), dirs))
if a.get("total_entries") != len(disk_names):
errs.append("total_entries artifact=%s recomputed=%d"
% (a.get("total_entries"), len(disk_names)))
if a.get("entries") is None or len(a["entries"]) != len(disk_names):
errs.append("entries length != disk count")
for e in a.get("entries", []):
want = recomputed.get(e["name"])
if want != e.get("class"):
errs.append("class mismatch %s: artifact=%r recompute=%r"
% (e["name"], e.get("class"), want))
if e.get("class") not in ALLOWED:
errs.append("unknown class label %r" % (e.get("class"),))
if errs:
print("CHECK FAIL")
for e in errs:
print(" -", e)
return 1
print("CHECK OK: %d entries, %d files, %d dirs; artifact == independently "
"recomputed disk state" % (len(disk_names), files, dirs))
return 0
if __name__ == "__main__":
sys.exit(main())