From 77f0fda5cbab741ddf65aeec5309033b20caca7b Mon Sep 17 00:00:00 2001 From: sol Date: Sun, 1 Nov 2026 19:43:16 +0000 Subject: [PATCH] sol: classification audit of sol profile directory; .skills_prompt_snapshot.json mislabeled state_db (correct: config_data) --- ...rofile-triage-classify-audit-2026-11-01.md | 57 +++++++ wizard-work/sol/verify_classify_audit.py | 151 ++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 wizard-work/sol/sol-profile-triage-classify-audit-2026-11-01.md create mode 100644 wizard-work/sol/verify_classify_audit.py diff --git a/wizard-work/sol/sol-profile-triage-classify-audit-2026-11-01.md b/wizard-work/sol/sol-profile-triage-classify-audit-2026-11-01.md new file mode 100644 index 0000000..df1b046 --- /dev/null +++ b/wizard-work/sol/sol-profile-triage-classify-audit-2026-11-01.md @@ -0,0 +1,57 @@ +# Sol profile directory — classification audit (2026-11-01) + +Independent re-derivation of the top-level classification of the live sol +profile `/root/.hermes/profiles/sol`, cross-checked against the committed +sol-profile triage artifacts. + +## Method + +1. `os.listdir` the live profile (69 top-level entries). +2. Classify each entry with an independent rule table (exact-name sets for + identity/config/state_db; named sets for cache/backups/logs/plugins/sessions/ + skills/vault; `.yaml`/`.json` files -> config_data; `.py` files -> script; + any other file -> other). +3. Re-derive category counts from disk and compare against every committed + 2026-11-01 / 2026-11-02 sol-profile triage JSON. + +## Live re-derived classification (69 entries) + +| category | count | +|---|---| +| backups | 1 | +| cache | 3 | +| config | 3 | +| config_data | 2 | +| extension_dir | 18 | +| identity | 2 | +| logs | 1 | +| other | 3 | +| plugins | 2 | +| script | 20 | +| sessions | 1 | +| skills | 1 | +| soul | 1 | +| state_db | 10 | +| vault | 1 | + +## Findings + +- The committed **2026-11-02** `sol-profile-triage-2026-11-02.json` matches the + live re-derivation exactly (69/69 entries, counts reconcile, category labels in + vocabulary). Baseline confirmed correct. +- The committed **2026-11-01** JSON `wizard-work/sol/sol-profile-triage-2026-11-01.json` + records `.skills_prompt_snapshot.json` as **`state_db`**, but the live + re-derivation (and the independent `.json`-suffix fallback rule) labels it + **`config_data`**. The companion uppercase artifact + `wizard-work/sol/Sol-Profile-Triage-2026-11-01.json` records `config_data` + (correct) — so the lowercase 11-01 record is the one with the error. +- Impact: one entry in one committed summary file is mislabeled. Correct label is + `config_data`. + +## Verdict + +VERDICT: audit OK — live re-derivation (69 entries) matches the committed +2026-11-02 baseline; the committed 2026-11-01 (lowercase) JSON mislabels +`.skills_prompt_snapshot.json` as state_db but the correct label is config_data. + +CHECK: python3 wizard-work/sol/verify_classify_audit.py diff --git a/wizard-work/sol/verify_classify_audit.py b/wizard-work/sol/verify_classify_audit.py new file mode 100644 index 0000000..b1365ce --- /dev/null +++ b/wizard-work/sol/verify_classify_audit.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +"""Independent verification of the sol-profile directory classification audit. + +Re-derives the top-level classification of the live sol profile from disk using +an independent rule table, then checks three things: + + (a) the committed 2026-11-02 sol-profile-triage JSON matches the live + re-derivation exactly (known-good baseline); + (b) the committed 2026-11-01 JSON (lowercase) records + .skills_prompt_snapshot.json as state_db, which DIFFERS from the live + re-derivation (config_data) - i.e. the audit finding is reproducible; + (c) the 2026-11-01 JSON (uppercase Sol-Profile-Triage...) matches the live + re-derivation exactly (known-good reference). + +Exit 0 = audit confirmed (verdict correct); nonzero = verdict wrong. + +Run from the troupe repo root, e.g.: + python3 wizard-work/sol/verify_classify_audit.py +""" +import json +import os +import sys + +HERE = os.path.dirname(os.path.abspath(__file__)) +REPO = os.path.dirname(os.path.dirname(HERE)) # troupe repo root + +PROFILE = "/root/.hermes/profiles/sol" +AUDIT_JSON = os.path.join(REPO, "wizard-work", "sol", + "sol-profile-triage-2026-11-01.json") +REF_JSON = os.path.join(REPO, "wizard-work", "sol", + "Sol-Profile-Triage-2026-11-01.json") +BASELINE_JSON = os.path.join(REPO, "wizard-work", "sol", + "sol-profile-triage-2026-11-02.json") + +KEY_FILE = ".skills_prompt_snapshot.json" +EXPECTED_LIVE = "config_data" # independent rule: any .json not in exact-name set is config_data +EXPECTED_RECORDED = "state_db" # the audit finding: the lowercase 11-01 record + + +def classify(name): + IDENTITY = {".env", ".env.bak-20261014T165715Z"} + CONFIG = {".env.lock", "config.yaml", "config.yaml.bak-20261014T165715Z"} + STATE_DB = { + "auth.json", "auth.lock", + "state.db", "state.db-shm", "state.db-wal", + "state.db.auto-maintenance.lock", "state.db.fts_rebuild.lock", + "state.db.quarantine.lock", + "models_dev_cache.etag", "models_dev_cache.json", + } + CACHE_DIRS = {"audio_cache", "cache", "image_cache"} + PLUGIN_DIRS = {"plugin-update-checks", "plugins"} + LOG_DIRS = {"logs"} + BACKUP_DIRS = {"backups"} + VAULT_DIRS = {"vault"} + SESSIONS_DIRS = {"sessions"} + SKILLS_DIRS = {"skills"} + SPECIAL_FILES = {"SOUL.md", "gateway.lock", "projects.db", + "context_length_cache.yaml", "context_length_cache.yaml.lock"} + + if name in IDENTITY: + return "identity" + if name in CONFIG: + return "config" + if name in STATE_DB: + return "state_db" + if name == "SOUL.md": + return "soul" + if name in ("gateway.lock", "projects.db"): + return "other" + if name in SPECIAL_FILES: + return "config_data" if name == "context_length_cache.yaml" else "other" + if os.path.isdir(os.path.join(PROFILE, name)): + if name in CACHE_DIRS: + return "cache" + if name in PLUGIN_DIRS: + return "plugins" + if name in LOG_DIRS: + return "logs" + if name in BACKUP_DIRS: + return "backups" + if name in VAULT_DIRS: + return "vault" + if name in SESSIONS_DIRS: + return "sessions" + if name in SKILLS_DIRS: + return "skills" + return "extension_dir" + if name.endswith((".yaml", ".json")): + return "config_data" + if name.endswith(".py"): + return "script" + return "other" + + +def load_entries(path): + with open(path, encoding="utf-8") as fh: + art = json.load(fh) + if isinstance(art, dict) and isinstance(art.get("entries"), list): + return {e.get("name"): e.get("category") for e in art["entries"]} + return {} + + +def main(): + errs = [] + + disk = sorted(os.listdir(PROFILE)) + live_counts = {} + for n in disk: + c = classify(n) + live_counts[c] = live_counts.get(c, 0) + 1 + + if len(disk) != 69: + errs.append("expected 69 live entries, got %d" % len(disk)) + + # (a) baseline: 2026-11-02 committed artifact matches live. + baseline = load_entries(BASELINE_JSON) + if baseline != {n: classify(n) for n in disk}: + errs.append("2026-11-02 baseline does not match live") + + # (b) audit finding: lowercase 11-01 records state_db for the key file + # while the live re-derivation says config_data. + audit = load_entries(AUDIT_JSON) + if audit.get(KEY_FILE) != EXPECTED_RECORDED: + errs.append("audit JSON record for %s is %r, expected %r" + % (KEY_FILE, audit.get(KEY_FILE), EXPECTED_RECORDED)) + if classify(KEY_FILE) != EXPECTED_LIVE: + errs.append("live re-derivation for %s is %r, expected %r" + % (KEY_FILE, classify(KEY_FILE), EXPECTED_LIVE)) + + # (c) reference: 2026-11-01 CAPS artifact matches live. + ref = load_entries(REF_JSON) + if ref != {n: classify(n) for n in disk}: + errs.append("CAPS 11-01 reference does not match live") + + if errs: + print("VERIFY FAIL") + for e in errs: + print(" -", e) + return 1 + + print("VERIFY OK") + print(" live entries: %d" % len(disk)) + print(" .skills_prompt_snapshot.json live=%s (recorded=%s)" % ( + classify(KEY_FILE), audit.get(KEY_FILE))) + print(" 2026-11-02 baseline matches live: True") + print(" CAPS 11-01 reference matches live: True") + return 0 + + +if __name__ == "__main__": + sys.exit(main())