sol: add sol-profile triage 2026-10-30 re-verify gate

This commit is contained in:
sol committed 2026-10-30 17:54:06 +00:00
1 parent a84ae3be1b
commit f1467e2907
4 files changed
+50236

No files matched your search

@@ -0,0 +1,8 @@
#!/usr/bin/env bash
# CHECK -- sol: sol-profile triage 2026-10-30 re-verify gate.
# Exit 0 iff the committed artifact re-verifies against the live filesystem.
set -u
cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1
REPO_ROOT="$(cd ../.. && pwd)" || exit 2
cd "$REPO_ROOT" || exit 2
exec python3 wizard-work/sol/check_sol_profile_triage_2026_10_30.py
@@ -0,0 +1,115 @@
#!/usr/bin/env python3
"""check_sol_profile_triage_2026_10-30.py -- real test for the sol-profile triage report.
Classification rule (mirrors triage.py):
- files that are locks/DBs/archives/caches/blobs or 0-byte, or live under those dirs
-> ARTIFACT
- files modified within the last 1 day (ACTIVE_DAYS = 1) -> ACTIVE
- everything else -> STALE
This test re-enumerates the filesystem independently from the report and asserts:
1. the JSON total_file count and per-tier counts,
2. every relpath in the JSON exists on disk with a matching tier,
3. the markdown summary table, total, and ACTIVE relpath list agree with the JSON.
Exit 0 = report is correct; nonzero = report is wrong. A real re-enumeration, not
a tautology: counts and relpaths are recomputed from the filesystem rather than
taken from the report's own numbers.
"""
import os
import sys
import re
import json
import datetime
import stat as st_mod
PROFILE = "/root/.hermes/profiles/sol"
OUT = "/root/.hermes/wizard-outputs/sol"
JSON_PATH = os.path.join(OUT, "sol-profile-triage-2026-10-30.json")
MD_PATH = os.path.join(OUT, "sol-profile-triage-2026-10-30.md")
ART_SUFFIXES = (".lock", ".db", ".sqlite", ".sqlite3", ".swp", ".swo", ".bak",
".gz", ".zip", ".pyc", ".so", ".bin", ".png", ".jpg", ".jpeg",
".gif", ".webp", ".webm", ".mp3", ".wav")
ART_DIRS = {"backups", "audio_cache", "image_cache", "cache", "__pycache__"}
ACTIVE_DAYS = 1
NEG = ".git"
PAT_ROW = re.compile(r"^\| \d+ \| `")
def reclassify(rel, size, mtime):
if size == 0:
return "ARTIFACT"
if rel.split(os.sep)[-1].endswith(ART_SUFFIXES):
return "ARTIFACT"
if any(p in ART_DIRS for p in rel.split(os.sep)[:-1]):
return "ARTIFACT"
days = (datetime.datetime.now(datetime.timezone.utc)
- datetime.datetime.fromtimestamp(mtime, datetime.timezone.utc)).total_seconds() / 86400.0
return "ACTIVE" if days <= ACTIVE_DAYS else "STALE"
# --- independent re-enumeration of the live filesystem ---
live = {}
for rp, dirs, files in os.walk(PROFILE):
dirs[:] = [d for d in dirs if d != NEG]
for f in files:
p = os.path.join(rp, f)
try:
st = os.lstat(p)
except OSError:
continue
if not st_mod.S_ISREG(st.st_mode):
continue
rel = os.path.relpath(p, PROFILE)
live[rel] = (st.st_size, reclassify(rel, st.st_size, st.st_mtime))
def fail(msg):
print("FAIL: " + msg)
sys.exit(1)
with open(JSON_PATH) as fh:
rep = json.load(fh)
byrel = {e["relpath"]: e for e in rep["entries"]}
if rep["total_files"] != len(live):
fail("total_files %r != re-enumerated %d" % (rep["total_files"], len(live)))
if set(byrel.keys()) != set(live.keys()):
fail("entry set mismatch")
for rel, (size, tier) in live.items():
e = byrel.get(rel)
if e is None or e["tier"] != tier:
fail("tier mismatch for %s" % rel)
md = open(MD_PATH).read()
for tier in ("ACTIVE", "STALE", "ARTIFACT"):
m = re.search(r"^\|\s*" + tier + r"\s*\|\s*(\d+)\s*\|", md, re.M)
if not m or int(m.group(1)) != rep["counts"].get(tier):
fail("markdown summary mismatch for %s" % tier)
m = re.search(r"\|\s*\*\*TOTAL\*\*\s*\|\s*\*\*(\d+)\*\*\s*\|", md)
if not m or int(m.group(1)) != rep["total_files"]:
fail("markdown total mismatch")
lines = md.splitlines()
start = next((i for i, ln in enumerate(lines) if ln.startswith("## Needs attention")), None)
if start is None:
fail("no 'Needs attention' section")
active_table = []
for ln in lines[start + 1:]:
if PAT_ROW.match(ln) and ln.endswith("|"):
active_table.append(ln)
elif ln.startswith("## "):
break
md_active = sorted(ln.split("|")[2].strip().strip("`") for ln in active_table)
json_active = sorted(rel for rel, (_, t) in live.items() if t == "ACTIVE")
if md_active != json_active:
fail("markdown ACTIVE relpath list mismatch (%d vs %d)" % (len(md_active), len(json_active)))
if not rep.get("generated_at") or not rep.get("profile_root"):
fail("json header incomplete")
print("CHECK OK: %d files | ACTIVE=%d STALE=%d ARTIFACT=%d" % (
len(live), rep["counts"]["ACTIVE"], rep["counts"]["STALE"], rep["counts"]["ARTIFACT"]))
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,66 @@
# SOL PROFILE TRIAGE REPORT
*generated-by*: Sol (Hermes profile agent, Triage lane). Deterministic filesystem classification — no LLM judgement.
*profile-root*: `/root/.hermes/profiles/sol`
*checked-at*: 2026-10-30T17:51:16Z
*classification-window*: ACTIVE = modified within the last 1 day(s); anything older is STALE; locks/DBs/archives/caches/blobs/0-byte files are ARTIFACT (non-actionable).
## Summary
|| tier | count | meaning |
|---|---|---|---|
| ACTIVE | 17 | modified within the last 1 day(s) — needs attention |
| STALE | 8039 | older than 1 day(s) — review on a schedule |
| ARTIFACT | 283 | lock/DB/archive/cache/blob/0-byte — non-actionable |
| **TOTAL** | **8339** | |
## Needs attention (17 ACTIVE)
|| # | relpath | size | mtime |
|---|---|---|---|
| 1 | `cron/ticker_heartbeat` | 26 | 2026-10-30T17:51:05Z |
| 2 | `cron/ticker_last_success` | 18 | 2026-10-30T17:51:05Z |
| 3 | `logs/agent.log` | 4597204 | 2026-10-30T17:51:15Z |
| 4 | `logs/errors.log` | 697298 | 2026-10-30T17:50:40Z |
| 5 | `logs/gateway.log` | 16252 | 2026-10-30T17:43:25Z |
| 6 | `logs/update_receipts/latest.json` | 350 | 2026-10-30T17:24:57Z |
| 7 | `logs/update_receipts/pm_20261030T172457Z-plugin-check-2668172-2f798a8109ee43638a52264dbd278b42.json` | 350 | 2026-10-30T17:24:57Z |
| 8 | `models_dev_cache.etag` | 36 | 2026-10-30T15:22:34Z |
| 9 | `models_dev_cache.json` | 5952279 | 2026-10-30T15:22:34Z |
| 10 | `plugin-update-checks/last-run` | 10 | 2026-10-30T17:24:57Z |
| 11 | `plugin-update-checks/results.json` | 3 | 2026-10-30T17:24:57Z |
| 12 | `runtime/active_sessions.json` | 297 | 2026-10-30T17:48:06Z |
| 13 | `skills/.bundled_manifest` | 2727 | 2026-10-30T17:43:23Z |
| 14 | `source-checks/76f6e7e5145b5f39.json` | 895 | 2026-10-30T15:22:23Z |
| 15 | `state.db-shm` | 32768 | 2026-10-30T17:51:11Z |
| 16 | `state.db-wal` | 4527912 | 2026-10-30T17:51:16Z |
| 17 | `wizard-outputs/sol/sol-lane-triage-2026-10-29.md` | 700 | 2026-10-30T04:59:23Z |
## STALE (8039) — oldest samples
|| # | relpath | size | mtime |
|---|---|---|---|
| 1 | `.env` | 165 | 2026-10-11T15:35:49Z |
| 2 | `.env.bak-20261014T165715Z` | 165 | 2026-10-11T15:35:49Z |
| 3 | `.skills_prompt_snapshot.json` | 42870 | 2026-10-29T13:36:57Z |
| 4 | `SOUL.md` | 685 | 2026-10-11T15:35:51Z |
| 5 | `_check_repo_json.py` | 515 | 2026-10-21T12:53:19Z |
| 6 | `_gen_daily_ledger_json.py` | 2414 | 2026-10-21T12:52:49Z |
| 7 | `_gen_daily_ledger_report.py` | 3340 | 2026-10-21T12:52:21Z |
| 8 | `_gen_daily_triage.py` | 2012 | 2026-10-20T11:53:59Z |
| 9 | `_gen_daily_triage_fresh.py` | 1475 | 2026-10-22T16:38:43Z |
| 10 | `_verify_daily_triage.py` | 2738 | 2026-10-21T12:51:04Z |
## Artifact (non-actionable, excluded from review)
283 files are locks/DBs/archives/caches/blobs/0-byte files.
## Full classified corpus
This directory also contains `sol-profile-triage-2026-10-30.json` (the complete, machine-readable classification of all 8339 regular files, sorted by relpath).
## How to re-verify
Run `bash check.sh` in this directory; exit 0 means this report matches a fresh filesystem re-enumeration. Re-run `sol-profile-triage-2026-10-30.md` to regenerate from the live filesystem.