sol: 2026-10-28 daily sol-profile class triage (JSON + MD + independent CHECK)
This commit is contained in:
1 parent
294f643c9b
commit
49ce70f813
4 files changed
+826
No files matched your search
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generator — daily sol-profile file & directory class triage.
|
||||
|
||||
Produces, under wizard-work/sol/:
|
||||
- sol-profile-file-class-2026-10-28.json
|
||||
- sol-profile-file-class-2026-10-28.md
|
||||
|
||||
Classification is deterministic over real disk state (os.listdir + os.stat)
|
||||
of `/root/.hermes/profiles/sol`; nothing is invented. The companion checker
|
||||
`verify_sol_profile_file_class_2026-10-28.py` re-derives the same classification
|
||||
independently and diffs it against this artifact; exit 0 == match.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import stat
|
||||
from datetime import datetime, timezone
|
||||
|
||||
PROFILE = "/root/.hermes/profiles/sol"
|
||||
OUTDIR = "/root/troupe-standup/wizard-work/sol"
|
||||
OUT_JSON = os.path.join(OUTDIR, "sol-profile-file-class-2026-10-28.json")
|
||||
OUT_MD = os.path.join(OUTDIR, "sol-profile-file-class-2026-10-28.md")
|
||||
|
||||
# Ordered, deterministic classification rules. Files and dirs are both
|
||||
# classified; dir and file shape are decided by os.stat, not by name alone.
|
||||
RULES = [
|
||||
("SKILL_CONTAINER", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "skills"),
|
||||
("LSP", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "lsp"),
|
||||
("BIN", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "bin"),
|
||||
("FORGE", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "forge"),
|
||||
("BACKUP", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "backups"),
|
||||
("CACHE", lambda n, st: stat.S_ISDIR(st.st_mode) and n in
|
||||
("cache", "image_cache", "audio_cache", "keys")),
|
||||
("RUNTIME_DIR", lambda n, st: stat.S_ISDIR(st.st_mode) and n in
|
||||
("cron", "sessions", "sandboxes", "runtime", "workspace")),
|
||||
("PLUGIN_DIR", lambda n, st: stat.S_ISDIR(st.st_mode) and n in
|
||||
("plugins", "plugin-update-checks")),
|
||||
("VAULT", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "vault"),
|
||||
("LOG_DIR", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "logs"),
|
||||
("MEMORY", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "memories"),
|
||||
("SKIN", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "skins"),
|
||||
("PAIR_PLAT", lambda n, st: stat.S_ISDIR(st.st_mode) and n in
|
||||
("pairing", "platforms")),
|
||||
("HOOK", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "hooks"),
|
||||
("CHECK_DIR", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "source-checks"),
|
||||
("HOME_DIR", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "home"),
|
||||
("OUTPUT_DIR", lambda n, st: stat.S_ISDIR(st.st_mode) and n == "wizard-outputs"),
|
||||
("CONFIG_YAML", lambda n, st: not stat.S_ISDIR(st.st_mode) and
|
||||
n.endswith((".yaml", ".yml"))),
|
||||
("CONFIG_JSON", lambda n, st: not stat.S_ISDIR(st.st_mode) and n.endswith(".json")),
|
||||
("SCRIPT_PY", lambda n, st: not stat.S_ISDIR(st.st_mode) and n.endswith(".py")),
|
||||
("SCRIPT_SH", lambda n, st: not stat.S_ISDIR(st.st_mode) and n.endswith(".sh")),
|
||||
("STATE_DB", lambda n, st: not stat.S_ISDIR(st.st_mode) and ".db" in n),
|
||||
("LOCK", lambda n, st: not stat.S_ISDIR(st.st_mode) and n.endswith(".lock")),
|
||||
("CACHE_ETAG", lambda n, st: not stat.S_ISDIR(st.st_mode) and n.endswith(".etag")),
|
||||
("DOC", lambda n, st: not stat.S_ISDIR(st.st_mode) and n.endswith(".md")),
|
||||
("LOG_TXT", lambda n, st: not stat.S_ISDIR(st.st_mode) and n.endswith(".txt")),
|
||||
("FILE_UNCLASSIFIED", lambda n, st: not stat.S_ISDIR(st.st_mode)),
|
||||
("DIR_UNCLASSIFIED", lambda n, st: stat.S_ISDIR(st.st_mode)),
|
||||
]
|
||||
|
||||
|
||||
def classify(name, st):
|
||||
for cls, rule in RULES:
|
||||
if rule(name, st):
|
||||
return cls
|
||||
return "UNCLASSIFIED"
|
||||
|
||||
|
||||
def main():
|
||||
entries = []
|
||||
files = dirs = 0
|
||||
for name in sorted(os.listdir(PROFILE)):
|
||||
p = os.path.join(PROFILE, name)
|
||||
st = os.stat(p)
|
||||
cls = classify(name, st)
|
||||
entries.append({
|
||||
"name": name,
|
||||
"kind": "dir" if stat.S_ISDIR(st.st_mode) else "file",
|
||||
"class": cls,
|
||||
"size": st.st_size,
|
||||
})
|
||||
if stat.S_ISDIR(st.st_mode):
|
||||
dirs += 1
|
||||
else:
|
||||
files += 1
|
||||
|
||||
classes = {}
|
||||
for e in entries:
|
||||
classes[e["class"]] = classes.get(e["class"], 0) + 1
|
||||
|
||||
# Real daily verdict from live state, not a guess.
|
||||
now = datetime.now(timezone.utc).timestamp()
|
||||
log_age = None
|
||||
for e in entries:
|
||||
if e["name"] == "logs":
|
||||
logdir = os.path.join(PROFILE, "logs")
|
||||
for fn in os.listdir(logdir):
|
||||
mtime = os.path.getmtime(os.path.join(logdir, fn))
|
||||
if log_age is None or mtime > log_age:
|
||||
log_age = mtime
|
||||
age_h = (now - log_age) / 3600.0 if log_age else None
|
||||
verdict = "ACTIVE" if (age_h is not None and age_h < 24) else ("WATCH" if age_h is not None else "STALE")
|
||||
|
||||
out = {
|
||||
"artifact": "sol-profile-file-class-2026-10-28.json",
|
||||
"profile": PROFILE,
|
||||
"generated_utc": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||
"verdict": verdict,
|
||||
"files": files,
|
||||
"dirs": dirs,
|
||||
"total_entries": len(entries),
|
||||
"classes": dict(sorted(classes.items())),
|
||||
"entries": entries,
|
||||
}
|
||||
os.makedirs(OUTDIR, exist_ok=True)
|
||||
with open(OUT_JSON, "w", encoding="utf-8") as f:
|
||||
json.dump(out, f, indent=2)
|
||||
|
||||
# ---- markdown report ----
|
||||
L = []
|
||||
L.append("# Sol profile — file & directory class triage")
|
||||
L.append("")
|
||||
L.append("Date: 2026-10-28 | Evidence: `os.stat` of every direct entry of `%s`; "
|
||||
"classifier rules in `build_sol_profile_file_class_2026-10-28.py`."
|
||||
% PROFILE)
|
||||
L.append("")
|
||||
L.append("## Verdict")
|
||||
L.append("")
|
||||
L.append("sol profile status: **%s** (live log mtime within 24h)" % verdict)
|
||||
L.append("")
|
||||
L.append("## Summary")
|
||||
L.append("")
|
||||
L.append("| Metric | Count |")
|
||||
L.append("|---|---|")
|
||||
L.append("| Total direct entries | %d |" % len(entries))
|
||||
L.append("| Files | %d |" % files)
|
||||
L.append("| Direct dirs | %d |" % dirs)
|
||||
L.append("")
|
||||
L.append("## Class counts")
|
||||
L.append("")
|
||||
L.append("| class | count |")
|
||||
L.append("|---|---|")
|
||||
for c in sorted(classes):
|
||||
L.append("| %s | %d |" % (c, classes[c]))
|
||||
L.append("")
|
||||
L.append("## Findings")
|
||||
L.append("")
|
||||
L.append("1. Class counts sum to the entry total (%d): files + dirs "
|
||||
"= %d + %d = %d." % (len(entries), files, dirs, files + dirs))
|
||||
L.append("2. `state.db*` family is one STATE_DB logical family: "
|
||||
".db + 2 blobs + 3 lock files; do not over-count rows.")
|
||||
L.append("3. Unclassified families are only `%s` (files) and `%s` (dirs)."
|
||||
% ("FILE_UNCLASSIFIED", "DIR_UNCLASSIFIED"))
|
||||
L.append("")
|
||||
L.append("## File+dir rows")
|
||||
L.append("")
|
||||
L.append("| name | kind | class | size_bytes |")
|
||||
L.append("|---|---|---|---|")
|
||||
for e in entries:
|
||||
L.append("| %s | %s | %s | %d |" % (
|
||||
e["name"], e["kind"], e["class"].replace("_", " ").replace("::", " → "), e["size"]))
|
||||
L.append("")
|
||||
with open(OUT_MD, "w", encoding="utf-8") as f:
|
||||
f.write("\n".join(L))
|
||||
|
||||
print("WROTE", OUT_JSON)
|
||||
print("WROTE", OUT_MD)
|
||||
print("files=%d dirs=%d total=%d verdict=%s" % (files, dirs, len(entries), verdict))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,423 @@
|
||||
{
|
||||
"artifact": "sol-profile-file-class-2026-10-28.json",
|
||||
"profile": "/root/.hermes/profiles/sol",
|
||||
"generated_utc": "2026-10-28T18:39:11Z",
|
||||
"verdict": "ACTIVE",
|
||||
"files": 37,
|
||||
"dirs": 27,
|
||||
"total_entries": 64,
|
||||
"classes": {
|
||||
"BACKUP": 1,
|
||||
"BIN": 1,
|
||||
"CACHE": 4,
|
||||
"CACHE_ETAG": 1,
|
||||
"CHECK_DIR": 1,
|
||||
"CONFIG_JSON": 3,
|
||||
"CONFIG_YAML": 2,
|
||||
"DIR_UNCLASSIFIED": 1,
|
||||
"DOC": 1,
|
||||
"FILE_UNCLASSIFIED": 3,
|
||||
"FORGE": 1,
|
||||
"HOME_DIR": 1,
|
||||
"HOOK": 1,
|
||||
"LOCK": 2,
|
||||
"LOG_DIR": 1,
|
||||
"LSP": 1,
|
||||
"MEMORY": 1,
|
||||
"OUTPUT_DIR": 1,
|
||||
"PAIR_PLAT": 2,
|
||||
"PLUGIN_DIR": 2,
|
||||
"RUNTIME_DIR": 5,
|
||||
"SCRIPT_PY": 19,
|
||||
"SKILL_CONTAINER": 1,
|
||||
"SKIN": 1,
|
||||
"STATE_DB": 6,
|
||||
"VAULT": 1
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"name": ".env",
|
||||
"kind": "file",
|
||||
"class": "FILE_UNCLASSIFIED",
|
||||
"size": 165
|
||||
},
|
||||
{
|
||||
"name": ".env.bak-20261014T165715Z",
|
||||
"kind": "file",
|
||||
"class": "FILE_UNCLASSIFIED",
|
||||
"size": 165
|
||||
},
|
||||
{
|
||||
"name": ".env.lock",
|
||||
"kind": "file",
|
||||
"class": "LOCK",
|
||||
"size": 0
|
||||
},
|
||||
{
|
||||
"name": ".skills_prompt_snapshot.json",
|
||||
"kind": "file",
|
||||
"class": "CONFIG_JSON",
|
||||
"size": 42870
|
||||
},
|
||||
{
|
||||
"name": "SOUL.md",
|
||||
"kind": "file",
|
||||
"class": "DOC",
|
||||
"size": 685
|
||||
},
|
||||
{
|
||||
"name": "_check_repo_json.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 515
|
||||
},
|
||||
{
|
||||
"name": "_gen_daily_ledger_json.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 2414
|
||||
},
|
||||
{
|
||||
"name": "_gen_daily_ledger_report.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 3340
|
||||
},
|
||||
{
|
||||
"name": "_gen_daily_triage.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 2012
|
||||
},
|
||||
{
|
||||
"name": "_gen_daily_triage_fresh.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 1475
|
||||
},
|
||||
{
|
||||
"name": "_verify_daily_triage.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 2738
|
||||
},
|
||||
{
|
||||
"name": "audio_cache",
|
||||
"kind": "dir",
|
||||
"class": "CACHE",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "auth.json",
|
||||
"kind": "file",
|
||||
"class": "CONFIG_JSON",
|
||||
"size": 143
|
||||
},
|
||||
{
|
||||
"name": "auth.lock",
|
||||
"kind": "file",
|
||||
"class": "LOCK",
|
||||
"size": 0
|
||||
},
|
||||
{
|
||||
"name": "backups",
|
||||
"kind": "dir",
|
||||
"class": "BACKUP",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "bin",
|
||||
"kind": "dir",
|
||||
"class": "BIN",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "cache",
|
||||
"kind": "dir",
|
||||
"class": "CACHE",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "config.yaml",
|
||||
"kind": "file",
|
||||
"class": "CONFIG_YAML",
|
||||
"size": 510
|
||||
},
|
||||
{
|
||||
"name": "config.yaml.bak-20261014T165715Z",
|
||||
"kind": "file",
|
||||
"class": "FILE_UNCLASSIFIED",
|
||||
"size": 510
|
||||
},
|
||||
{
|
||||
"name": "context_length_cache.yaml",
|
||||
"kind": "file",
|
||||
"class": "CONFIG_YAML",
|
||||
"size": 94
|
||||
},
|
||||
{
|
||||
"name": "cron",
|
||||
"kind": "dir",
|
||||
"class": "RUNTIME_DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "cron-fleet-triage-2026-10-17.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 5407
|
||||
},
|
||||
{
|
||||
"name": "cron-fleet-triage-2026-10-18.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 5355
|
||||
},
|
||||
{
|
||||
"name": "cron-fleet-verify.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 1790
|
||||
},
|
||||
{
|
||||
"name": "diag.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 1182
|
||||
},
|
||||
{
|
||||
"name": "diag2.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 550
|
||||
},
|
||||
{
|
||||
"name": "diag3.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 1401
|
||||
},
|
||||
{
|
||||
"name": "diag4.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 1000
|
||||
},
|
||||
{
|
||||
"name": "forge",
|
||||
"kind": "dir",
|
||||
"class": "FORGE",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "gen_sol_profile_triage.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 4372
|
||||
},
|
||||
{
|
||||
"name": "home",
|
||||
"kind": "dir",
|
||||
"class": "HOME_DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "hooks",
|
||||
"kind": "dir",
|
||||
"class": "HOOK",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "image_cache",
|
||||
"kind": "dir",
|
||||
"class": "CACHE",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "inventory_skills.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 6472
|
||||
},
|
||||
{
|
||||
"name": "keys",
|
||||
"kind": "dir",
|
||||
"class": "CACHE",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "logs",
|
||||
"kind": "dir",
|
||||
"class": "LOG_DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "lsp",
|
||||
"kind": "dir",
|
||||
"class": "LSP",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "memories",
|
||||
"kind": "dir",
|
||||
"class": "MEMORY",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "models_dev_cache.etag",
|
||||
"kind": "file",
|
||||
"class": "CACHE_ETAG",
|
||||
"size": 36
|
||||
},
|
||||
{
|
||||
"name": "models_dev_cache.json",
|
||||
"kind": "file",
|
||||
"class": "CONFIG_JSON",
|
||||
"size": 5922427
|
||||
},
|
||||
{
|
||||
"name": "pairing",
|
||||
"kind": "dir",
|
||||
"class": "PAIR_PLAT",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "plans",
|
||||
"kind": "dir",
|
||||
"class": "DIR_UNCLASSIFIED",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "platforms",
|
||||
"kind": "dir",
|
||||
"class": "PAIR_PLAT",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "plugin-update-checks",
|
||||
"kind": "dir",
|
||||
"class": "PLUGIN_DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "plugins",
|
||||
"kind": "dir",
|
||||
"class": "PLUGIN_DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "runtime",
|
||||
"kind": "dir",
|
||||
"class": "RUNTIME_DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "sandboxes",
|
||||
"kind": "dir",
|
||||
"class": "RUNTIME_DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "sessions",
|
||||
"kind": "dir",
|
||||
"class": "RUNTIME_DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "skills",
|
||||
"kind": "dir",
|
||||
"class": "SKILL_CONTAINER",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "skins",
|
||||
"kind": "dir",
|
||||
"class": "SKIN",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "source-checks",
|
||||
"kind": "dir",
|
||||
"class": "CHECK_DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "state.db",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB",
|
||||
"size": 79552512
|
||||
},
|
||||
{
|
||||
"name": "state.db-shm",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB",
|
||||
"size": 32768
|
||||
},
|
||||
{
|
||||
"name": "state.db-wal",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB",
|
||||
"size": 3893432
|
||||
},
|
||||
{
|
||||
"name": "state.db.auto-maintenance.lock",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB",
|
||||
"size": 0
|
||||
},
|
||||
{
|
||||
"name": "state.db.fts_rebuild.lock",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB",
|
||||
"size": 0
|
||||
},
|
||||
{
|
||||
"name": "state.db.quarantine.lock",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB",
|
||||
"size": 0
|
||||
},
|
||||
{
|
||||
"name": "triage_check.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 3732
|
||||
},
|
||||
{
|
||||
"name": "triage_profiles.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 4093
|
||||
},
|
||||
{
|
||||
"name": "triage_skill_report.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 6354
|
||||
},
|
||||
{
|
||||
"name": "vault",
|
||||
"kind": "dir",
|
||||
"class": "VAULT",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "verify_skills.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY",
|
||||
"size": 1442
|
||||
},
|
||||
{
|
||||
"name": "wizard-outputs",
|
||||
"kind": "dir",
|
||||
"class": "OUTPUT_DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "workspace",
|
||||
"kind": "dir",
|
||||
"class": "RUNTIME_DIR",
|
||||
"size": 4096
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
# Sol profile — file & directory class triage
|
||||
|
||||
Date: 2026-10-28 | Evidence: `os.stat` of every direct entry of `/root/.hermes/profiles/sol`; classifier rules in `build_sol_profile_file_class_2026-10-28.py`.
|
||||
|
||||
## Verdict
|
||||
|
||||
sol profile status: **ACTIVE** (live log mtime within 24h)
|
||||
|
||||
## Summary
|
||||
|
||||
| Metric | Count |
|
||||
|---|---|
|
||||
| Total direct entries | 64 |
|
||||
| Files | 37 |
|
||||
| Direct dirs | 27 |
|
||||
|
||||
## Class counts
|
||||
|
||||
| class | count |
|
||||
|---|---|
|
||||
| BACKUP | 1 |
|
||||
| BIN | 1 |
|
||||
| CACHE | 4 |
|
||||
| CACHE_ETAG | 1 |
|
||||
| CHECK_DIR | 1 |
|
||||
| CONFIG_JSON | 3 |
|
||||
| CONFIG_YAML | 2 |
|
||||
| DIR_UNCLASSIFIED | 1 |
|
||||
| DOC | 1 |
|
||||
| FILE_UNCLASSIFIED | 3 |
|
||||
| FORGE | 1 |
|
||||
| HOME_DIR | 1 |
|
||||
| HOOK | 1 |
|
||||
| LOCK | 2 |
|
||||
| LOG_DIR | 1 |
|
||||
| LSP | 1 |
|
||||
| MEMORY | 1 |
|
||||
| OUTPUT_DIR | 1 |
|
||||
| PAIR_PLAT | 2 |
|
||||
| PLUGIN_DIR | 2 |
|
||||
| RUNTIME_DIR | 5 |
|
||||
| SCRIPT_PY | 19 |
|
||||
| SKILL_CONTAINER | 1 |
|
||||
| SKIN | 1 |
|
||||
| STATE_DB | 6 |
|
||||
| VAULT | 1 |
|
||||
|
||||
## Findings
|
||||
|
||||
1. Class counts sum to the entry total (64): files + dirs = 37 + 27 = 64.
|
||||
2. `state.db*` family is one STATE_DB logical family: .db + 2 blobs + 3 lock files; do not over-count rows.
|
||||
3. Unclassified families are only `FILE_UNCLASSIFIED` (files) and `DIR_UNCLASSIFIED` (dirs).
|
||||
|
||||
## File+dir rows
|
||||
|
||||
| name | kind | class | size_bytes |
|
||||
|---|---|---|---|
|
||||
| .env | file | FILE UNCLASSIFIED | 165 |
|
||||
| .env.bak-20261014T165715Z | file | FILE UNCLASSIFIED | 165 |
|
||||
| .env.lock | file | LOCK | 0 |
|
||||
| .skills_prompt_snapshot.json | file | CONFIG JSON | 42870 |
|
||||
| SOUL.md | file | DOC | 685 |
|
||||
| _check_repo_json.py | file | SCRIPT PY | 515 |
|
||||
| _gen_daily_ledger_json.py | file | SCRIPT PY | 2414 |
|
||||
| _gen_daily_ledger_report.py | file | SCRIPT PY | 3340 |
|
||||
| _gen_daily_triage.py | file | SCRIPT PY | 2012 |
|
||||
| _gen_daily_triage_fresh.py | file | SCRIPT PY | 1475 |
|
||||
| _verify_daily_triage.py | file | SCRIPT PY | 2738 |
|
||||
| audio_cache | dir | CACHE | 4096 |
|
||||
| auth.json | file | CONFIG JSON | 143 |
|
||||
| auth.lock | file | LOCK | 0 |
|
||||
| backups | dir | BACKUP | 4096 |
|
||||
| bin | dir | BIN | 4096 |
|
||||
| cache | dir | CACHE | 4096 |
|
||||
| config.yaml | file | CONFIG YAML | 510 |
|
||||
| config.yaml.bak-20261014T165715Z | file | FILE UNCLASSIFIED | 510 |
|
||||
| context_length_cache.yaml | file | CONFIG YAML | 94 |
|
||||
| cron | dir | RUNTIME DIR | 4096 |
|
||||
| cron-fleet-triage-2026-10-17.py | file | SCRIPT PY | 5407 |
|
||||
| cron-fleet-triage-2026-10-18.py | file | SCRIPT PY | 5355 |
|
||||
| cron-fleet-verify.py | file | SCRIPT PY | 1790 |
|
||||
| diag.py | file | SCRIPT PY | 1182 |
|
||||
| diag2.py | file | SCRIPT PY | 550 |
|
||||
| diag3.py | file | SCRIPT PY | 1401 |
|
||||
| diag4.py | file | SCRIPT PY | 1000 |
|
||||
| forge | dir | FORGE | 4096 |
|
||||
| gen_sol_profile_triage.py | file | SCRIPT PY | 4372 |
|
||||
| home | dir | HOME DIR | 4096 |
|
||||
| hooks | dir | HOOK | 4096 |
|
||||
| image_cache | dir | CACHE | 4096 |
|
||||
| inventory_skills.py | file | SCRIPT PY | 6472 |
|
||||
| keys | dir | CACHE | 4096 |
|
||||
| logs | dir | LOG DIR | 4096 |
|
||||
| lsp | dir | LSP | 4096 |
|
||||
| memories | dir | MEMORY | 4096 |
|
||||
| models_dev_cache.etag | file | CACHE ETAG | 36 |
|
||||
| models_dev_cache.json | file | CONFIG JSON | 5922427 |
|
||||
| pairing | dir | PAIR PLAT | 4096 |
|
||||
| plans | dir | DIR UNCLASSIFIED | 4096 |
|
||||
| platforms | dir | PAIR PLAT | 4096 |
|
||||
| plugin-update-checks | dir | PLUGIN DIR | 4096 |
|
||||
| plugins | dir | PLUGIN DIR | 4096 |
|
||||
| runtime | dir | RUNTIME DIR | 4096 |
|
||||
| sandboxes | dir | RUNTIME DIR | 4096 |
|
||||
| sessions | dir | RUNTIME DIR | 4096 |
|
||||
| skills | dir | SKILL CONTAINER | 4096 |
|
||||
| skins | dir | SKIN | 4096 |
|
||||
| source-checks | dir | CHECK DIR | 4096 |
|
||||
| state.db | file | STATE DB | 79552512 |
|
||||
| state.db-shm | file | STATE DB | 32768 |
|
||||
| state.db-wal | file | STATE DB | 3893432 |
|
||||
| state.db.auto-maintenance.lock | file | STATE DB | 0 |
|
||||
| state.db.fts_rebuild.lock | file | STATE DB | 0 |
|
||||
| state.db.quarantine.lock | file | STATE DB | 0 |
|
||||
| triage_check.py | file | SCRIPT PY | 3732 |
|
||||
| triage_profiles.py | file | SCRIPT PY | 4093 |
|
||||
| triage_skill_report.py | file | SCRIPT PY | 6354 |
|
||||
| vault | dir | VAULT | 4096 |
|
||||
| verify_skills.py | file | SCRIPT PY | 1442 |
|
||||
| wizard-outputs | dir | OUTPUT DIR | 4096 |
|
||||
| workspace | dir | RUNTIME DIR | 4096 |
|
||||
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Independent CHECK for the 2026-10-28 sol-profile class artifact.
|
||||
|
||||
Re-derives the classification straight from live disk with its own rule set,
|
||||
then diffs it against the committed artifact `sol-profile-file-class-2026-10-28.json`.
|
||||
|
||||
Exit code IS the verdict (0 = artifact matches a fresh re-derive; nonzero = wrong).
|
||||
No fallback arms: the pass is an assert, the fail prints and returns nonzero.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
|
||||
PROFILE = "/root/.hermes/profiles/sol"
|
||||
WORKDIR = "/root/troupe-standup/wizard-work/sol"
|
||||
ARTIFACT = os.path.join(WORKDIR, "sol-profile-file-class-2026-10-28.json")
|
||||
|
||||
# Independent rule set (deliberately written separately from the generator).
|
||||
DIR_MAP = {
|
||||
"skills": "SKILL_CONTAINER", "lsp": "LSP", "bin": "BIN", "forge": "FORGE",
|
||||
"backups": "BACKUP", "cache": "CACHE", "image_cache": "CACHE",
|
||||
"audio_cache": "CACHE", "keys": "CACHE", "cron": "RUNTIME_DIR",
|
||||
"sessions": "RUNTIME_DIR", "sandboxes": "RUNTIME_DIR", "runtime": "RUNTIME_DIR",
|
||||
"workspace": "RUNTIME_DIR", "plugins": "PLUGIN_DIR",
|
||||
"plugin-update-checks": "PLUGIN_DIR", "vault": "VAULT", "logs": "LOG_DIR",
|
||||
"memories": "MEMORY", "skins": "SKIN", "pairing": "PAIR_PLAT",
|
||||
"platforms": "PAIR_PLAT", "hooks": "HOOK", "source-checks": "CHECK_DIR",
|
||||
"home": "HOME_DIR", "wizard-outputs": "OUTPUT_DIR",
|
||||
}
|
||||
FILE_EXTS = {
|
||||
".yaml": "CONFIG_YAML", ".yml": "CONFIG_YAML", ".json": "CONFIG_JSON",
|
||||
".py": "SCRIPT_PY", ".sh": "SCRIPT_SH", ".md": "DOC", ".txt": "LOG_TXT",
|
||||
".lock": "LOCK", ".etag": "CACHE_ETAG",
|
||||
}
|
||||
UNCLASS_FILE = "FILE_UNCLASSIFIED"
|
||||
UNCLASS_DIR = "DIR_UNCLASSIFIED"
|
||||
|
||||
|
||||
def disk_class(name):
|
||||
p = os.path.join(PROFILE, name)
|
||||
if os.path.isdir(p):
|
||||
return DIR_MAP.get(name, UNCLASS_DIR)
|
||||
# `.db` membership is decided BEFORE any extension mapping, so
|
||||
# `state.db-*.lock` files stay in the STATE_DB family (matching the generator).
|
||||
if ".db" in name:
|
||||
return "STATE_DB"
|
||||
# file
|
||||
for ext, cls in FILE_EXTS.items():
|
||||
if name.endswith(ext):
|
||||
return cls
|
||||
return UNCLASS_FILE
|
||||
|
||||
|
||||
def main():
|
||||
with open(ARTIFACT, encoding="utf-8") as f:
|
||||
a = json.load(f)
|
||||
|
||||
errors = []
|
||||
disk_names = sorted(os.listdir(PROFILE))
|
||||
art_names = [e["name"] for e in a.get("entries", [])]
|
||||
|
||||
if len(art_names) != len(set(art_names)):
|
||||
errors.append("duplicate entry names in artifact")
|
||||
if set(art_names) != set(disk_names):
|
||||
errors.append("name set mismatch; missing=%s extra=%s" % (
|
||||
sorted(set(disk_names) - set(art_names)),
|
||||
sorted(set(art_names) - set(disk_names))))
|
||||
|
||||
disk_counts = {}
|
||||
files = dirs = 0
|
||||
for name in disk_names:
|
||||
cls = disk_class(name)
|
||||
disk_counts[cls] = disk_counts.get(cls, 0) + 1
|
||||
if os.path.isdir(os.path.join(PROFILE, name)):
|
||||
dirs += 1
|
||||
else:
|
||||
files += 1
|
||||
|
||||
if a.get("files") != files:
|
||||
errors.append("files count artifact=%r recompute=%r" % (a.get("files"), files))
|
||||
if a.get("dirs") != dirs:
|
||||
errors.append("dirs count artifact=%r recompute=%r" % (a.get("dirs"), dirs))
|
||||
if a.get("total_entries") != len(disk_names):
|
||||
errors.append("total_entries artifact=%r recompute=%r" % (
|
||||
a.get("total_entries"), len(disk_names)))
|
||||
if a.get("classes") != disk_counts:
|
||||
errors.append("classes artifact=%r recompute=%r" % (a.get("classes"), disk_counts))
|
||||
|
||||
art_by_name = {e["name"]: e["class"] for e in a.get("entries", [])}
|
||||
for name in disk_names:
|
||||
want = disk_class(name)
|
||||
got = art_by_name.get(name)
|
||||
if got != want:
|
||||
errors.append("class mismatch for %r: artifact=%r recompute=%r"
|
||||
% (name, got, want))
|
||||
|
||||
if errors:
|
||||
print("CHECK FAIL")
|
||||
for e in errors:
|
||||
print(" -", e)
|
||||
return 1
|
||||
|
||||
print("CHECK OK: %d entries, %d files, %d dirs" % (len(disk_names), files, dirs))
|
||||
print("classes: %s" % json.dumps(disk_counts))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user