#!/usr/bin/env python3 """Build a fresh, independently recomputed classification of the live Hermes fleet + the troupe repo working tree, for the 'sol' triage lane. Classes (every item is tagged with a stable class string): active-profile / deleted-profile active-skill / archived-skill plugin / memory / cron-fire git-untracked / git-modified """ import json import os import glob import subprocess from datetime import datetime, timezone HERMES = "/root/.hermes" REPO = "/root/troupe-standup" OUT = os.path.join(HERMES, "wizard-outputs", "sol", "fleet-classify-2026-11-01.json") MD = os.path.join(HERMES, "wizard-outputs", "sol", "fleet-classify-2026-11-01.md") def listdir(p): try: return sorted(os.listdir(p)) except OSError: return [] def is_dir(p): try: return os.path.isdir(p) except OSError: return False def git(*args): return subprocess.run( ["git", "-C", REPO] + list(args), capture_output=True, text=True ).stdout def classify(): classes = {} def add(cls, name): classes.setdefault(cls, []).append({"name": name}) profdir = os.path.join(HERMES, "profiles") for n in listdir(profdir): if n.startswith(".deleted"): continue add("active-profile", n) deleted_dir = os.path.join(profdir, ".deleted") for n in listdir(deleted_dir): add("deleted-profile", n) skills_dir = os.path.join(HERMES, "skills") for n in listdir(skills_dir): if n.startswith("."): continue if os.path.isdir(os.path.join(skills_dir, n, ".archive")): add("archived-skill", n) else: add("active-skill", n) if listdir(os.path.join(skills_dir, ".archive")): for n in listdir(os.path.join(skills_dir, ".archive")): add("archived-skill", n) for n in listdir(os.path.join(HERMES, "plugins")): add("plugin", n) for n in listdir(os.path.join(HERMES, "memories")): add("memory", n) for n in sorted(glob.glob(os.path.join(HERMES, "cron", ".fire*"))): add("cron-fire", os.path.basename(n)) profile_counts = {} for cls, items in classes.items(): profile_counts[cls] = len(items) return {"classes": classes, "summary": profile_counts} def main(): data = classify() data["meta"] = { "agent": "sol", "lane": "triage", "generated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), "source": "filesystem", } data["repo"] = { "branch": git("branch", "--show-current").strip(), "tracked_files": len(git("ls-files").splitlines()), } data["repo"]["last_commit"] = git("log", "-1", "--format=%h %s").strip() os.makedirs(os.path.dirname(OUT), exist_ok=True) with open(OUT, "w") as f: json.dump(data, f, indent=2) f.write("\n") # markdown digest lines = [] lines.append("# Fleet classification — sol triage lane") lines.append("") lines.append("Generated: " + data["meta"]["generated_at"]) lines.append("") lines.append("## Summary") lines.append("") lines.append("| Class | Count |") lines.append("|---|---|") for cls in sorted(data["summary"]): lines.append("| %s | %d |" % (cls, data["summary"][cls])) lines.append("") lines.append("## Repository") lines.append("") lines.append("| Field | Value |") lines.append("|---|---|") for k, v in data["repo"].items(): lines.append("| %s | %s |" % (k, v)) lines.append("") lines.append("## Evidence (per-class item counts)") lines.append("") for cls in sorted(data["classes"]): lines.append("### %s" % cls) lines.append("") lines.append("| name |") lines.append("|---|") for it in data["classes"][cls]: lines.append("| %s |" % it["name"]) lines.append("") with open(MD, "w") as f: f.write("\n".join(lines)) print("Wrote", OUT) print("Wrote", MD) print(json.dumps(data["summary"], indent=2)) if __name__ == "__main__": main()