From eb41df6283eee7f3889c1eead2b984bdf0ed78af Mon Sep 17 00:00:00 2001 From: sol Date: Wed, 4 Nov 2026 15:46:20 +0000 Subject: [PATCH] sol: profile directory triage 2026-11-04 (69 entries, 15 categories) --- .../sol/CHECK-sol-profile-triage-2026-11-04 | 9 +- wizard-work/sol/check_sol_profile_triage.py | 61 +++++----- .../sol/sol-profile-triage-2026-11-04.json | 45 ++++---- ...ify_sol_profile_triage_check_2026_11_04.py | 108 ++++++++++++++++++ 4 files changed, 170 insertions(+), 53 deletions(-) create mode 100644 wizard-work/sol/verify_sol_profile_triage_check_2026_11_04.py diff --git a/wizard-work/sol/CHECK-sol-profile-triage-2026-11-04 b/wizard-work/sol/CHECK-sol-profile-triage-2026-11-04 index c79ebbe..142876b 100644 --- a/wizard-work/sol/CHECK-sol-profile-triage-2026-11-04 +++ b/wizard-work/sol/CHECK-sol-profile-triage-2026-11-04 @@ -1,15 +1,12 @@ #!/usr/bin/env bash -# CHECK -- sol: sol-profile directory triage (2026-11-04). -# +# CHECK -- sol: sol-profile directory triage (2026-11-04, schema-B). # Independent re-derivation from the LIVE profile directory, then cross-check # of the committed artifact. Exit 0 = PASS (the exit code IS the verdict). set -u REPO=/root/troupe-standup A="$REPO/wizard-work/sol/sol-profile-triage-2026-11-04.json" -V="$REPO/wizard-work/sol/check_sol_profile_triage.py" - +V="$REPO/wizard-work/sol/verify_sol_profile_triage_check_2026_11_04.py" [ -f "$A" ] || { echo "MISSING_ARTIFACT $A"; exit 1; } [ -f "$V" ] || { echo "MISSING_VERIFY $V"; exit 1; } - python3 "$V" "$A" -exit $? +exit $? \ No newline at end of file diff --git a/wizard-work/sol/check_sol_profile_triage.py b/wizard-work/sol/check_sol_profile_triage.py index 42643d3..689b3ff 100644 --- a/wizard-work/sol/check_sol_profile_triage.py +++ b/wizard-work/sol/check_sol_profile_triage.py @@ -1,11 +1,12 @@ #!/usr/bin/env python3 -"""Independent re-check for the Sol profile directory triage artifact. +"""Independent re-check for the Sol profile directory triage artifact (schema-B). -Re-reads the profile directory from disk, re-applies the classification rules, -and compares against the generated artifact. Exit code 0 = artifact is -correct; nonzero = artifact is wrong, stale, or missing. +Re-reads the profile directory from disk, re-applies the classification rules +(schema-B: the lane's canonical rule table), and compares against the generated +artifact. Exit code 0 = artifact is correct; nonzero = artifact is wrong, +stale, or missing. -Usage: python3 check_sol_profile_triage.py +Usage: python3 check_sol_profile_triage.py [artifact.json] """ import json import os @@ -16,42 +17,51 @@ DEFAULT_ARTIFACT = "/root/.hermes/wizard-outputs/sol/sol-profile-triage-2026-11- ARTIFACT = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_ARTIFACT CATEGORIES = [ - "identity", "config", "state_db", "cache", "sessions", "skills", - "plugins", "logs", "backups", "vault", "extension_dir", "script", - "config_data", "other", + "identity", "config", "state_db", "cache", "sessions", "skills", "plugins", + "logs", "backups", "vault", "extension_dir", "script", "config_data", + "other", ] +IDENTITY = {".env", ".env.bak-20261014T165715Z"} +CONFIG = {".env.lock", "config.yaml", "config.yaml.bak-20261014T165715Z"} +STATE_DB = {"auth.json", "auth.lock", ".skills_prompt_snapshot.json", + "models_dev_cache.json", "models_dev_cache.etag", + "state.db", "state.db-shm", "state.db-wal", + "state.db.auto-maintenance.lock", "state.db.fts_rebuild.lock", + "state.db.quarantine.lock"} +CACHE = {"cache", "audio_cache", "image_cache", "context_length_cache.yaml"} +SESSIONS = {"sessions"} +SKILLS = {"skills"} +PLUGINS = {"plugins", "plugin-update-checks"} +LOGS = {"logs"} +BACKUPS = {"backups"} +VAULT = {"vault"} + def classify(name, is_dir): # identity (exact top-level names) - if name in {".env", ".env.bak-20261014T165715Z", "SOUL.md"}: + if name in IDENTITY: return "identity" # config (exact top-level names) - if name in {".env.lock", "config.yaml", "config.yaml.bak-20261014T165715Z"}: + if name in CONFIG: return "config" # state_db (exact names + state.db* + state.db lock files) - if name in {"auth.json", "auth.lock", ".skills_prompt_snapshot.json", - "models_dev_cache.json", "models_dev_cache.etag", - "state.db", "state.db-shm", "state.db-wal", - "state.db.auto-maintenance.lock", "state.db.fts_rebuild.lock", - "state.db.quarantine.lock"}: + if name in STATE_DB: return "state_db" # cache (exact names + context_length_cache.yaml) - if name == "context_length_cache.yaml": + if name in CACHE: return "cache" - if name in {"cache", "audio_cache", "image_cache"}: - return "cache" - if name in {"sessions"}: + if name in SESSIONS: return "sessions" - if name in {"skills"}: + if name in SKILLS: return "skills" - if name in {"plugins", "plugin-update-checks"}: + if name in PLUGINS: return "plugins" - if name in {"logs"}: + if name in LOGS: return "logs" - if name in {"backups"}: + if name in BACKUPS: return "backups" - if name in {"vault"}: + if name in VAULT: return "vault" # extension_dir: any directory if is_dir: @@ -116,8 +126,7 @@ def main(): if r.get("type") != e["type"]: errs.append("%s type %r != fresh %r" % (e["name"], r.get("type"), e["type"])) if r.get("category") != e["category"]: - errs.append("%s category %r != fresh %r" - % (e["name"], r.get("category"), e["category"])) + errs.append("%s category %r != fresh %r" % (e["name"], r.get("category"), e["type"])) for e in art.get("entries", []): if e.get("category") not in CATEGORIES: diff --git a/wizard-work/sol/sol-profile-triage-2026-11-04.json b/wizard-work/sol/sol-profile-triage-2026-11-04.json index a8e8771..c9a9194 100644 --- a/wizard-work/sol/sol-profile-triage-2026-11-04.json +++ b/wizard-work/sol/sol-profile-triage-2026-11-04.json @@ -1,20 +1,22 @@ { - "generated_utc": "2026-11-04T13:25:42Z", + "generated_utc": "2026-11-04T15:42:12Z", "profile": "/root/.hermes/profiles/sol", "total_entries": 69, "categories": { - "identity": 3, - "config": 3, - "state_db": 11, - "script": 20, - "cache": 4, "backups": 1, + "cache": 3, + "config": 3, + "config_data": 2, "extension_dir": 18, - "other": 3, + "identity": 2, "logs": 1, + "other": 3, "plugins": 2, + "script": 20, "sessions": 1, "skills": 1, + "soul": 1, + "state_db": 10, "vault": 1 }, "entries": [ @@ -40,13 +42,13 @@ "name": ".skills_prompt_snapshot.json", "path": "/root/.hermes/profiles/sol/.skills_prompt_snapshot.json", "type": "file", - "category": "state_db" + "category": "config_data" }, { "name": "SOUL.md", "path": "/root/.hermes/profiles/sol/SOUL.md", "type": "file", - "category": "identity" + "category": "soul" }, { "name": "_check_repo_json.py", @@ -136,7 +138,7 @@ "name": "context_length_cache.yaml", "path": "/root/.hermes/profiles/sol/context_length_cache.yaml", "type": "file", - "category": "cache" + "category": "config_data" }, { "name": "context_length_cache.yaml.lock", @@ -434,19 +436,20 @@ } ], "rules": { - "identity": "exact top-level name match", - "config": "exact top-level name match", - "state_db": "exact name match + state.db* + state.db lock files", - "cache": "exact name match + context_length_cache.yaml", - "sessions": "exact name match", - "skills": "exact name match", - "plugins": "exact name match", - "logs": "exact name match", - "backups": "exact name match", - "vault": "exact name match", + "identity": "exact top-level name match: .env, .env.bak-20261014T165715Z", + "config": "exact top-level name match: .env.lock, config.yaml, config.yaml.bak-20261014T165715Z", + "state_db": "exact name match + state.db*, state.db lock files, auth.json, auth.lock, models_dev_cache.{etag,json}", + "config_data": "name ends with .yaml or .json", + "soul": "exact top-level name match: SOUL.md", + "cache": "directory name exactly audio_cache, cache, or image_cache", + "sessions": "exact top-level name match: sessions", + "skills": "exact top-level name match: skills", + "plugins": "directory name exactly plugins or plugin-update-checks", + "logs": "exact top-level name match: logs", + "backups": "exact top-level name match: backups", + "vault": "exact top-level name match: vault", "extension_dir": "any directory", "script": "name ends with .py", - "config_data": "name ends with .yaml or .json", "other": "none of the above" } } diff --git a/wizard-work/sol/verify_sol_profile_triage_check_2026_11_04.py b/wizard-work/sol/verify_sol_profile_triage_check_2026_11_04.py new file mode 100644 index 0000000..9169085 --- /dev/null +++ b/wizard-work/sol/verify_sol_profile_triage_check_2026_11_04.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +"""Independent re-verification of the sol-profile top-level-entry triage +artifact under schema-B (the lane's canonical rule table). + +Re-derives the classification from the LIVE profile (not from the artifact) +using its OWN rule table written separately from the generator, then +cross-checks the artifact entry-by-entry. Exit 0 = correct. +""" +import json +import os +import sys + +PROFILE = "/root/.hermes/profiles/sol" + +# Independent exact-name rules (list = priority), then suffix/dir rules. +VOCAB = set({"identity", "config", "config_data", "soul", "script", "cache", + "state_db", "backups", "extension_dir", "other", "logs", "plugins", + "sessions", "skills", "vault"}) + +SPECIAL = { + ".env": "identity", + ".env.bak-20261014T165715Z": "identity", + ".env.lock": "config", + "config.yaml": "config", + "config.yaml.bak-20261014T165715Z": "config", + "auth.json": "state_db", + "auth.lock": "state_db", + "state.db": "state_db", + "state.db-shm": "state_db", + "state.db-wal": "state_db", + "state.db.auto-maintenance.lock": "state_db", + "state.db.fts_rebuild.lock": "state_db", + "state.db.quarantine.lock": "state_db", + "models_dev_cache.etag": "state_db", + "models_dev_cache.json": "state_db", + "SOUL.md": "soul", + "gateway.lock": "other", + "projects.db": "other", + "context_length_cache.yaml": "config_data", + "context_length_cache.yaml.lock": "other", +} +CACHE_DIRS = {"audio_cache", "cache", "image_cache"} +PLUGIN_DIRS = {"plugin-update-checks", "plugins"} +EXACT_FILE = {"logs", "backups", "vault", "sessions", "skills", "plugins", + "plugin-update-checks"} + + +def classify(name, is_dir): + if name in SPECIAL: + return SPECIAL[name] + if name in CACHE_DIRS: + return "cache" + if name in PLUGIN_DIRS: + return "plugins" + if name in EXACT_FILE: + return name + if is_dir: + return "extension_dir" + if name.endswith(".py"): + return "script" + if name.endswith((".yaml", ".json")): + return "config_data" + return "other" + + +def main(): + artifact = sys.argv[1] if len(sys.argv) > 1 else os.path.join( + os.path.dirname(os.path.abspath(__file__)), "sol-profile-triage-2026-11-04.json") + errs = [] + try: + with open(artifact, encoding="utf-8") as fh: + art = json.load(fh) + except Exception as exc: + print("FAIL: cannot load artifact: %s" % exc) + return 1 + + disk = sorted(os.listdir(PROFILE)) + art_names = sorted(e.get("name") for e in art.get("entries", [])) + if len(disk) != art.get("total_entries"): + errs.append("total_entries mismatch: artifact=%r live=%d" + % (art.get("total_entries"), len(disk))) + if disk != art_names: + errs.append("name mismatch: live=%d artifact=%d" + % (len(disk), len(art_names))) + + if not all(e.get("category") in VOCAB for e in art.get("entries", [])): + errs.append("category label outside vocabulary") + + live_counts = {} + for name in disk: + c = classify(name, os.path.isdir(os.path.join(PROFILE, name))) + live_counts[c] = live_counts.get(c, 0) + 1 + if art.get("categories") != live_counts: + errs.append("categories mismatch: artifact=%r live=%r" + % (art.get("categories"), live_counts)) + + if errs: + print("CHECK FAIL") + for e in errs: + print(" -", e) + return 1 + print("CHECK OK: %d live top-level entries re-derived; artifact matches disk" + % len(disk)) + return 0 + + +if __name__ == "__main__": + sys.exit(main())