142 lines
4.7 KiB
Python
142 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Generate a real, filesystem-grounded SOL PROFILE TRIAGE report.
|
|
|
|
Scans every file under /root/.hermes/profiles/sol/ and classifies each one
|
|
into a category, then writes a markdown report to the troupe repo.
|
|
"""
|
|
import os
|
|
import sys
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
|
|
PROFILE_ROOT = Path("/root/.hermes/profiles/sol")
|
|
REPORT_PATH = Path(
|
|
"/root/troupe-standup/wizard-work/sol/sol-profile-triage-report.md"
|
|
)
|
|
|
|
|
|
def category_for(path: Path) -> str:
|
|
name = path.name.lower()
|
|
if path.suffix in (".py",):
|
|
return "script"
|
|
if path.suffix in (".yaml", ".yml", ".json", ".toml", ".env"):
|
|
return "config"
|
|
if path.suffix in (".db",):
|
|
return "data"
|
|
if path.suffix in (".lock",):
|
|
return "lock"
|
|
if path.suffix in (".mp3", ".wav", ".png", ".jpeg", ".jpg", ".etag"):
|
|
return "media"
|
|
if path.suffix in (".log",):
|
|
return "log"
|
|
if path.suffix in (".md", ".txt"):
|
|
return "doc"
|
|
if path.name in ("auth.json",):
|
|
return "secret"
|
|
if path.name == "state.db":
|
|
return "data"
|
|
return "other"
|
|
|
|
|
|
def main() -> int:
|
|
if not PROFILE_ROOT.is_dir():
|
|
print(f"FATAL: profile root missing: {PROFILE_ROOT}", file=sys.stderr)
|
|
return 1
|
|
|
|
files = []
|
|
for dirpath, dirnames, filenames in os.walk(PROFILE_ROOT):
|
|
dirnames.sort()
|
|
for fn in sorted(filenames):
|
|
p = Path(dirpath) / fn
|
|
try:
|
|
st = p.stat()
|
|
except OSError:
|
|
continue
|
|
files.append(
|
|
{
|
|
"rel": p.relative_to(PROFILE_ROOT).as_posix(),
|
|
"size": st.st_size,
|
|
"mtime": datetime.fromtimestamp(
|
|
st.st_mtime, tz=timezone.utc
|
|
).isoformat(),
|
|
"cat": category_for(p),
|
|
}
|
|
)
|
|
|
|
# Category rollup
|
|
cats = {}
|
|
for f in files:
|
|
cats.setdefault(f["cat"], []).append(f)
|
|
|
|
lines = []
|
|
w = lines.append
|
|
w("# SOL PROFILE TRIAGE REPORT")
|
|
w("")
|
|
w(f"*generated-by*: sol (Hermes profile agent)")
|
|
w(f"*generated-at*: {datetime.now(timezone.utc).isoformat()}")
|
|
w(f"*profile-root*: `{PROFILE_ROOT}`")
|
|
w(f"*file-count*: {len(files)}")
|
|
w(f"*total-size*: {sum(f['size'] for f in files):,} bytes")
|
|
w("")
|
|
w("## Category rollup")
|
|
w("")
|
|
w("| category | files | bytes | example |")
|
|
w("|---|---|---|---|")
|
|
for cat in sorted(cats):
|
|
examples = cats[cat][:2]
|
|
ex = ", ".join(f"`{e['rel']}`" for e in examples)
|
|
w(f"| {cat} | {len(cats[cat])} | {sum(e['size'] for e in cats[cat]):,} | {ex} |")
|
|
w("")
|
|
w("## File inventory")
|
|
w("")
|
|
w("| category | relpath | bytes | mtime(UTC) |")
|
|
w("|---|---|---|---|")
|
|
for f in sorted(files, key=lambda x: (x["cat"], x["rel"])):
|
|
w(f"| {f['cat']} | `{f['rel']}` | {f['size']:,} | {f['mtime']} |")
|
|
w("")
|
|
w("## Key facts")
|
|
w("")
|
|
for name in ("config.yaml", "SOUL.md", "auth.json", "models_dev_cache.json"):
|
|
p = PROFILE_ROOT / name
|
|
if not p.is_file():
|
|
continue
|
|
w(f"### `{name}`")
|
|
w("")
|
|
if name == "models_dev_cache.json":
|
|
# Summarize the model registry by provider instead of dumping
|
|
# the whole 5.9MB file; the raw file is unchanged on disk.
|
|
try:
|
|
import json
|
|
|
|
data = json.loads(p.read_text(encoding="utf-8", errors="replace"))
|
|
except Exception as exc: # pragma: no cover
|
|
w(f"(could not parse: {exc})")
|
|
continue
|
|
providers = data.get("providers", {})
|
|
w(f"*active_provider*: `{data.get('active_provider')}`")
|
|
w(f"*model_count*: {sum(len(v.get('models', {})) for v in providers.values())}")
|
|
w("*providers*: " + ", ".join(sorted(providers)))
|
|
w("*entries-eg*: " + ", ".join(
|
|
f"`{k}`" for k in list(providers.get("openai", {}).get("models", {}).keys())[:8]
|
|
))
|
|
else:
|
|
w("```")
|
|
with p.open("r", errors="replace") as fh:
|
|
w(fh.read())
|
|
w("```")
|
|
w("")
|
|
w("## Verdict")
|
|
w("")
|
|
w("Inventory complete. All entries below are measured from the live")
|
|
w(f"filesystem ({len(files)} files, {sum(f['size'] for f in files):,} bytes).")
|
|
w("")
|
|
REPORT_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
REPORT_PATH.write_text("\n".join(lines), encoding="utf-8")
|
|
print(f"wrote {REPORT_PATH}")
|
|
print(f"files={len(files)} bytes={sum(f['size'] for f in files):,} cats={len(cats)}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|