99 lines
3.2 KiB
Python
99 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
# Sol-lane daily profile-state triage -- verifier.
|
|
#
|
|
# Recomputes the category counts and headline totals for
|
|
# /root/.hermes/profiles/sol from the live filesystem using the shared
|
|
# classifier (sol_triage_lib), then asserts that the generated report
|
|
# (sol-lane-triage-2026-10-25.md) states exactly those numbers. Exit 0 only
|
|
# if every assertion passes; nonzero otherwise.
|
|
#
|
|
# Run: python3 /root/troupe-standup/wizard-work/sol/verify_sol_profile_triage.py
|
|
# Check (this file's exit code is the verdict):
|
|
# bash /root/troupe-standup/wizard-work/sol/verify_sol_profile_triage.sh
|
|
#
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
REPO_ROOT = '/root/troupe-standup'
|
|
SOL_LANE = os.path.join(REPO_ROOT, 'wizard-work', 'sol')
|
|
REPORT_PATH = os.path.join(SOL_LANE, 'sol-lane-triage-2026-10-25.md')
|
|
|
|
sys.path.insert(0, SOL_LANE)
|
|
import sol_triage_lib # noqa: E402
|
|
|
|
KNOWN_CATEGORIES = {
|
|
'config', 'state', 'cache', 'logs', 'skills', 'plugins', 'runtime', 'cron',
|
|
'backups', 'keys', 'vault', 'home', 'hooks', 'lsp', 'memories', 'pairing',
|
|
'plans', 'platforms', 'sandboxes', 'sessions', 'skins', 'forge', 'bin',
|
|
'workspace', 'other',
|
|
}
|
|
|
|
failures = []
|
|
|
|
|
|
def check(label, got, expected):
|
|
if got != expected:
|
|
failures.append('%s: report=%r recomputed=%r' % (label, got, expected))
|
|
|
|
|
|
def main():
|
|
d = sol_triage_lib.compute()
|
|
|
|
if not os.path.exists(REPORT_PATH):
|
|
print('VERDICT: RED (report missing: %s)' % REPORT_PATH)
|
|
return 1
|
|
|
|
with open(REPORT_PATH) as f:
|
|
text = f.read()
|
|
|
|
# Headline measure table: | files | 6479 | etc.
|
|
head_re = re.compile(r'^\|\s*(files|dirs|entries|stale \(>60 d\)[^|]*)\|?\s*\|?\s*(\d+)\s*\|', re.M)
|
|
head = {}
|
|
for m in head_re.finditer(text):
|
|
key = m.group(1).strip()
|
|
val = int(m.group(2))
|
|
if key in ('files', 'dirs', 'entries'):
|
|
head[key] = val
|
|
elif key.startswith('stale'):
|
|
head['stale'] = val
|
|
|
|
check('files', head.get('files'), d['total_files'])
|
|
check('dirs', head.get('dirs'), d['total_dirs'])
|
|
check('entries', head.get('entries'), d['total_entries'])
|
|
check('stale', head.get('stale'), d['stale_count'])
|
|
|
|
# Category table: | config | 12 | etc.
|
|
cat_re = re.compile(r'^\|\s*([A-Za-z0-9_]+)\s*\|\s*(\d+)\s*\|', re.M)
|
|
reported_cat = {}
|
|
for m in cat_re.finditer(text):
|
|
key = m.group(1)
|
|
if key in ('category', 'measure'):
|
|
continue
|
|
if key in KNOWN_CATEGORIES:
|
|
reported_cat[key] = int(m.group(2))
|
|
|
|
check('category totals sum', sum(reported_cat.values()), d['total_entries'])
|
|
for k, v in d['category_counts'].items():
|
|
check('category %s' % k, reported_cat.get(k), v)
|
|
|
|
print('recompute files=%s dirs=%s entries=%s stale=%s'
|
|
% (d['total_files'], d['total_dirs'], d['total_entries'], d['stale_count']))
|
|
print('recompute stale files/dirs = %s/%s'
|
|
% (d['stale_files'], d['stale_dirs']))
|
|
|
|
if failures:
|
|
print('VERDICT: RED (%d assertion(s) failed)' % len(failures))
|
|
for fl in failures:
|
|
print(' FAIL', fl)
|
|
return 1
|
|
|
|
print('VERDICT: GREEN (%d category counts + 4 headline totals all match)'
|
|
% (len(d['category_counts']) + 4))
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|