140 lines
4.7 KiB
Bash
140 lines
4.7 KiB
Bash
#!/usr/bin/env bash
|
|
# CHECK -- sol-profile file-class census 2026-11-04 (sol lane: "Triage").
|
|
#
|
|
# A real, machine-checkable test, not a tautology. It independently re-derives
|
|
# the classification of every top-level entry of the live sol profile
|
|
# (/root/.hermes/profiles/sol) from disk, then compares it entry-by-entry and
|
|
# in aggregate against the committed artifact
|
|
# (wizard-work/sol/sol-profile-file-class-2026-11-04.json).
|
|
#
|
|
# Exit 0 = correct (artifact matches an independent recomputation from disk)
|
|
# Exit != 0 = wrong.
|
|
#
|
|
# Usage: bash /root/troupe-standup/wizard-work/sol/CHECK-sol-profile-file-class-202
|
|
set -u
|
|
|
|
PROFILE="/root/.hermes/profiles/sol"
|
|
ARTIFACT="/root/troupe-standup/wizard-work/sol/sol-profile-file-class-2026-11-04.json"
|
|
|
|
python3 - "$PROFILE" "$ARTIFACT" <<'PYEOF'
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
profile, artifact = sys.argv[1], sys.argv[2]
|
|
|
|
|
|
def suffix_rule(name):
|
|
low = name.lower()
|
|
if low.endswith(".db"):
|
|
return "STATE_DB::FILE"
|
|
if low.endswith(".py"):
|
|
return "SCRIPT_PY::FILE"
|
|
if low.endswith(".sh"):
|
|
return "SCRIPT_SH::FILE"
|
|
if low.endswith((".yaml", ".yml")):
|
|
return "CONFIG_YAML::FILE"
|
|
if low.endswith(".json"):
|
|
return "CONFIG_JSON::FILE"
|
|
if low.endswith(".lock"):
|
|
return "LOCK::FILE"
|
|
if low.endswith(".md"):
|
|
return "DOC::FILE"
|
|
if low.endswith(".txt"):
|
|
return "LOG_TXT::FILE"
|
|
if low.endswith(".etag"):
|
|
return "CACHE_ETAG::FILE"
|
|
if low.endswith((".mp3", ".png", ".jpg", ".jpeg")):
|
|
return "ARTIFACT::FILE"
|
|
return "FILE::UNCLASSIFIED"
|
|
|
|
|
|
def dir_rule(name):
|
|
specials = {
|
|
"skills": "SKILL_CONTAINER::DIR",
|
|
"vault": "VAULT::DIR",
|
|
"memories": "MEMORY_DIR::DIR",
|
|
"logs": "LOG_DIR::DIR",
|
|
"cache": "CACHE_DIR::DIR",
|
|
"backups": "BACKUP_DIR::DIR",
|
|
"forge": "FORGE_DIR::DIR",
|
|
"bin": "BIN_DIR::DIR",
|
|
"lsp": "LSP_DIR::DIR",
|
|
"wizard-outputs": "OUTPUT_DIR::DIR",
|
|
}
|
|
return specials.get(name, "DIR::UNCLASSIFIED")
|
|
|
|
|
|
def recompute():
|
|
disk = sorted(os.listdir(profile))
|
|
counts = {}
|
|
for name in disk:
|
|
full = os.path.join(profile, name)
|
|
cls = dir_rule(name) if os.path.isdir(full) else suffix_rule(name)
|
|
counts[cls] = counts.get(cls, 0) + 1
|
|
return disk, counts
|
|
|
|
|
|
def main():
|
|
errs = []
|
|
try:
|
|
with open(artifact, encoding="utf-8") as fh:
|
|
art = json.load(fh)
|
|
except Exception as exc:
|
|
print("CHECK FAIL: cannot load artifact: %s" % exc)
|
|
return 1
|
|
|
|
try:
|
|
disk = sorted(os.listdir(profile))
|
|
except OSError as exc:
|
|
print("CHECK FAIL: cannot list profile: %s" % exc)
|
|
return 1
|
|
|
|
# (a) every live top-level entry must appear exactly once in the artifact.
|
|
art_names = [e.get("name") for e in art.get("entries", [])]
|
|
if len(art_names) != len(set(art_names)):
|
|
errs.append("duplicate entry names in artifact")
|
|
if set(art_names) != set(disk):
|
|
errs.append("name set mismatch: missing=%s extra=%s"
|
|
% (sorted(set(disk) - set(art_names)), sorted(set(art_names) - set(disk))))
|
|
|
|
# (b) counts must re-derive exactly from disk.
|
|
disk_names, live_counts = recompute()
|
|
live_files = sum(1 for n in disk_names if not os.path.isdir(os.path.join(profile, n)))
|
|
live_dirs = len(disk_names) - live_files
|
|
if art.get("counts") != {"file": live_files, "dir": live_dirs}:
|
|
errs.append("counts mismatch: artifact=%r live=%r"
|
|
% (art.get("counts"), {"file": live_files, "dir": live_dirs}))
|
|
if art.get("file_classes") != live_counts:
|
|
errs.append("file_classes mismatch: artifact=%r live=%r"
|
|
% (art.get("file_classes"), live_counts))
|
|
if art.get("total_entries") != len(disk_names):
|
|
errs.append("total_entries mismatch: artifact=%r live=%r"
|
|
% (art.get("total_entries"), len(disk_names)))
|
|
|
|
# (c) every entry's class label must equal an independent re-derivation.
|
|
for e in art.get("entries", []):
|
|
n = e.get("name")
|
|
if n not in disk:
|
|
errs.append("entry name not on disk: %r" % n)
|
|
continue
|
|
want = dir_rule(n) if os.path.isdir(os.path.join(profile, n)) else suffix_rule(n)
|
|
if e.get("class") != want:
|
|
errs.append("class mismatch for %s: artifact=%r recompute=%r"
|
|
% (n, e.get("class"), want))
|
|
|
|
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 from live profile disk" % (len(disk_names), live_files, live_dirs))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|
|
PYEOF
|