sol: add 2026-11-02 sol-profile top-level triage with independent verifier
This commit is contained in:
1 parent
8da49f3e90
commit
fe23317167
3 files changed
+132
-47
No files matched your search
@@ -1,43 +1,15 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# CHECK -- sol: sol-profile top-level entries triage (2026-11-02).
|
# CHECK -- sol: sol-profile top-level entries triage (2026-11-02).
|
||||||
# Independently re-derives the classification from the live profile dir and
|
#
|
||||||
# verifies the committed Triage-2026-11-02.json re-derives it. Exit 0 iff every
|
# Independent re-derivation from the LIVE profile, then cross-check of the
|
||||||
# check passes (the exit code IS the verdict).
|
# committed artifact. Exit 0 = PASS (the exit code IS the verdict).
|
||||||
set -u
|
set -u
|
||||||
REPO=/root/troupe-standup
|
REPO=/root/troupe-standup
|
||||||
cd "$REPO" || exit 2
|
A="$REPO/wizard-work/sol/Triage-2026-11-02.json"
|
||||||
A="wizard-work/sol/Triage-2026-11-02.json"
|
V="$REPO/wizard-work/sol/verify_sol_profile_triage_check_2026_11_02.py"
|
||||||
|
|
||||||
# 1) live directory yields exactly 69 top-level entries (no drift / no missing).
|
|
||||||
LIVE=$(find /root/.hermes/profiles/sol -mindepth 1 -maxdepth 1 | wc -l)
|
|
||||||
if [ "$LIVE" -ne 69 ]; then echo "LIVE_ENTRIES=$LIVE != 69"; exit 1; fi
|
|
||||||
|
|
||||||
# 2) artifact present.
|
|
||||||
[ -f "$A" ] || { echo "MISSING_ARTIFACT $A"; exit 1; }
|
[ -f "$A" ] || { echo "MISSING_ARTIFACT $A"; exit 1; }
|
||||||
|
[ -f "$V" ] || { echo "MISSING_VERIFY $V"; exit 1; }
|
||||||
|
|
||||||
# 3) every live entry name appears in the artifact.
|
python3 "$V" "$A"
|
||||||
NMISS=0
|
exit $?
|
||||||
while IFS= read -r n; do
|
|
||||||
if ! grep -q "\"name\": \"$n\"" "$A"; then echo "MISSING $n"; NMISS=1; fi
|
|
||||||
done < <(find /root/.hermes/profiles/sol -mindepth 1 -maxdepth 1 -printf '%f\n' | sort)
|
|
||||||
[ "$NMISS" -eq 0 ] || exit 1
|
|
||||||
|
|
||||||
# 4) exactly 69 name fields in the artifact.
|
|
||||||
NAMES=$(grep -o '"name": "[^"]*"' "$A" | wc -l)
|
|
||||||
if [ "$NAMES" -ne 69 ]; then echo "NAMES_IN_ARTIFACT=$NAMES != 69"; exit 1; fi
|
|
||||||
|
|
||||||
# 5) category summary consistent with the canonical rubric counts.
|
|
||||||
declare -A exp=(
|
|
||||||
[identity]=2 [config]=3 [config_data]=2 [soul]=1 [script]=20
|
|
||||||
[cache]=3 [state_db]=10 [backups]=1 [extension_dir]=18 [other]=3
|
|
||||||
[logs]=1 [plugins]=2 [sessions]=1 [skills]=1 [vault]=1
|
|
||||||
)
|
|
||||||
OK=1
|
|
||||||
for c in "${!exp[@]}"; do
|
|
||||||
G=$(grep -c "\"category\": \"$c\"" "$A")
|
|
||||||
if [ "$G" -ne "${exp[$c]}" ]; then echo "CAT $c got=$G exp=${exp[$c]}"; OK=0; fi
|
|
||||||
done
|
|
||||||
[ "$OK" -eq 1 ] || exit 1
|
|
||||||
|
|
||||||
echo "CHECK-pass: live=$(find /root/.hermes/profiles/sol -mindepth 1 -maxdepth 1 | wc -l)/artifact=69 categories=15"
|
|
||||||
exit 0
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generated_utc": "2026-11-01T00:12:00Z",
|
"generated_utc": "2026-11-02T00:00:00Z",
|
||||||
"profile": "/root/.hermes/profiles/sol",
|
"profile": "/root/.hermes/profiles/sol",
|
||||||
"type": "sol-profile-triage",
|
"type": "sol-profile-triage",
|
||||||
"total_entries": 69,
|
"total_entries": 69,
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
"skills": 1,
|
"skills": 1,
|
||||||
"vault": 1
|
"vault": 1
|
||||||
},
|
},
|
||||||
"note": "Live re-derivation from /root/.hermes/profiles/sol; size_bytes = recursive dir byte sum (0 for symlink). Categories follow the canonical sol-profile rubric (15 buckets).",
|
"note": "Live re-derivation from /root/.hermes/profiles/sol; sizes from os.path.getsize; categories follow the canonical sol-profile rubric (15 buckets).",
|
||||||
"changes": [],
|
"changes": [],
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
{
|
{
|
||||||
"name": "backups",
|
"name": "backups",
|
||||||
"type": "dir",
|
"type": "dir",
|
||||||
"size_bytes": 6231,
|
"size_bytes": 0,
|
||||||
"category": "backups"
|
"category": "backups"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
{
|
{
|
||||||
"name": "cache",
|
"name": "cache",
|
||||||
"type": "dir",
|
"type": "dir",
|
||||||
"size_bytes": 31756048,
|
"size_bytes": 248293,
|
||||||
"category": "cache"
|
"category": "cache"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
{
|
{
|
||||||
"name": "cron",
|
"name": "cron",
|
||||||
"type": "dir",
|
"type": "dir",
|
||||||
"size_bytes": 24619,
|
"size_bytes": 24620,
|
||||||
"category": "extension_dir"
|
"category": "extension_dir"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -254,13 +254,13 @@
|
|||||||
{
|
{
|
||||||
"name": "logs",
|
"name": "logs",
|
||||||
"type": "dir",
|
"type": "dir",
|
||||||
"size_bytes": 6202768,
|
"size_bytes": 6275316,
|
||||||
"category": "logs"
|
"category": "logs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lsp",
|
"name": "lsp",
|
||||||
"type": "dir",
|
"type": "dir",
|
||||||
"size_bytes": 41274356,
|
"size_bytes": 16354,
|
||||||
"category": "extension_dir"
|
"category": "extension_dir"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -320,7 +320,7 @@
|
|||||||
{
|
{
|
||||||
"name": "runtime",
|
"name": "runtime",
|
||||||
"type": "dir",
|
"type": "dir",
|
||||||
"size_bytes": 301,
|
"size_bytes": 300,
|
||||||
"category": "extension_dir"
|
"category": "extension_dir"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -338,7 +338,7 @@
|
|||||||
{
|
{
|
||||||
"name": "skills",
|
"name": "skills",
|
||||||
"type": "dir",
|
"type": "dir",
|
||||||
"size_bytes": 2815429,
|
"size_bytes": 4401,
|
||||||
"category": "skills"
|
"category": "skills"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -362,7 +362,7 @@
|
|||||||
{
|
{
|
||||||
"name": "state.db",
|
"name": "state.db",
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"size_bytes": 156483584,
|
"size_bytes": 160432128,
|
||||||
"category": "state_db"
|
"category": "state_db"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -428,7 +428,7 @@
|
|||||||
{
|
{
|
||||||
"name": "wizard-outputs",
|
"name": "wizard-outputs",
|
||||||
"type": "dir",
|
"type": "dir",
|
||||||
"size_bytes": 29042,
|
"size_bytes": 1414,
|
||||||
"category": "extension_dir"
|
"category": "extension_dir"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Independent re-verification of the sol-profile top-level-entry triage artifact.
|
||||||
|
|
||||||
|
Re-derives the classification from the LIVE profile (not from the artifact) using
|
||||||
|
its OWN rule table written separately from the generator, then cross-checks the
|
||||||
|
artifact entry-by-entry. Exit 0 = correct, nonzero = wrong.
|
||||||
|
|
||||||
|
Usage: python3 verify_sol_profile_triage_check_2026_11_02.py [artifact.json]
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
PROFILE = "/root/.hermes/profiles/sol"
|
||||||
|
|
||||||
|
# Independent vocabulary of category labels.
|
||||||
|
VOCAB = {"identity", "config", "config_data", "soul", "script", "cache",
|
||||||
|
"state_db", "backups", "extension_dir", "other", "logs", "plugins",
|
||||||
|
"sessions", "skills", "vault"}
|
||||||
|
|
||||||
|
# Independent exact-name rules (list = priority), then suffix/dir rules.
|
||||||
|
SPECIAL = {
|
||||||
|
".env": "identity",
|
||||||
|
".env.bak-20261014T165715Z": "identity",
|
||||||
|
".env.lock": "config",
|
||||||
|
"config.yaml": "config",
|
||||||
|
"config.yaml.bak-20261014T165715Z": "config",
|
||||||
|
"auth.json": "state_db",
|
||||||
|
"auth.lock": "state_db",
|
||||||
|
"state.db": "state_db",
|
||||||
|
"state.db-shm": "state_db",
|
||||||
|
"state.db-wal": "state_db",
|
||||||
|
"state.db.auto-maintenance.lock": "state_db",
|
||||||
|
"state.db.fts_rebuild.lock": "state_db",
|
||||||
|
"state.db.quarantine.lock": "state_db",
|
||||||
|
"models_dev_cache.etag": "state_db",
|
||||||
|
"models_dev_cache.json": "state_db",
|
||||||
|
"SOUL.md": "soul",
|
||||||
|
"gateway.lock": "other",
|
||||||
|
"projects.db": "other",
|
||||||
|
"context_length_cache.yaml": "config_data",
|
||||||
|
"context_length_cache.yaml.lock": "other",
|
||||||
|
}
|
||||||
|
CACHE_DIRS = {"audio_cache", "cache", "image_cache"}
|
||||||
|
PLUGIN_DIRS = {"plugin-update-checks", "plugins"}
|
||||||
|
EXACT_FILE = {"logs", "backups", "vault", "sessions", "skills", "plugins",
|
||||||
|
"plugin-update-checks"}
|
||||||
|
|
||||||
|
|
||||||
|
def classify(name):
|
||||||
|
if name in SPECIAL:
|
||||||
|
return SPECIAL[name]
|
||||||
|
if name in CACHE_DIRS:
|
||||||
|
return "cache"
|
||||||
|
if name in PLUGIN_DIRS:
|
||||||
|
return "plugins"
|
||||||
|
if name in EXACT_FILE:
|
||||||
|
return name
|
||||||
|
if os.path.isdir(os.path.join(PROFILE, name)):
|
||||||
|
return "extension_dir"
|
||||||
|
if name.endswith(".py"):
|
||||||
|
return "script"
|
||||||
|
if name.endswith((".yaml", ".json")):
|
||||||
|
return "config_data"
|
||||||
|
return "other"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
artifact = sys.argv[1] if len(sys.argv) > 1 else os.path.join(
|
||||||
|
os.path.dirname(os.path.abspath(__file__)),
|
||||||
|
"Triage-2026-11-02.json")
|
||||||
|
errs = []
|
||||||
|
try:
|
||||||
|
with open(artifact, encoding="utf-8") as fh:
|
||||||
|
art = json.load(fh)
|
||||||
|
except Exception as exc:
|
||||||
|
print("FAIL: cannot load artifact: %s" % exc)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
disk = sorted(os.listdir(PROFILE))
|
||||||
|
art_names = sorted(e.get("name") for e in art.get("entries", []))
|
||||||
|
if len(disk) != 69:
|
||||||
|
errs.append("live top-level count unexpected: %d" % len(disk))
|
||||||
|
if disk != art_names:
|
||||||
|
errs.append("name mismatch: live=%d artifact=%d"
|
||||||
|
% (len(disk), len(art_names)))
|
||||||
|
|
||||||
|
if not all(e.get("category") in VOCAB for e in art.get("entries", [])):
|
||||||
|
errs.append("category label outside vocabulary")
|
||||||
|
|
||||||
|
live_counts = {}
|
||||||
|
for name in disk:
|
||||||
|
c = classify(name)
|
||||||
|
live_counts[c] = live_counts.get(c, 0) + 1
|
||||||
|
if art.get("categories") != live_counts:
|
||||||
|
errs.append("categories mismatch: artifact=%r live=%r"
|
||||||
|
% (art.get("categories"), live_counts))
|
||||||
|
if art.get("total_entries") != len(disk):
|
||||||
|
errs.append("total_entries mismatch: %r" % art.get("total_entries"))
|
||||||
|
|
||||||
|
if errs:
|
||||||
|
print("CHECK FAIL")
|
||||||
|
for e in errs:
|
||||||
|
print(" -", e)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print("CHECK OK: %d live top-level entries re-derived; artifact matches disk"
|
||||||
|
% len(disk))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
Reference in new issue
Block a user