sol: file/dir class triage of sol profile
This commit is contained in:
1 parent
4a512b75ee
commit
193568c24a
4 files changed
+833
No files matched your search
@@ -0,0 +1,416 @@
|
||||
{
|
||||
"artifact": "sol-profile-file-class-2026-10-27.json",
|
||||
"profile": "/root/.hermes/profiles/sol",
|
||||
"generated_utc": "2026-10-27T11:35:14Z",
|
||||
"files": 36,
|
||||
"dirs": 27,
|
||||
"total_entries": 63,
|
||||
"classes": {
|
||||
"BACKUP::DIR": 1,
|
||||
"BIN::DIR": 1,
|
||||
"CACHE::DIR": 4,
|
||||
"CACHE_ETAG::FILE": 1,
|
||||
"CHECK_DIR::DIR": 1,
|
||||
"CONFIG_JSON::FILE": 3,
|
||||
"CONFIG_YAML::FILE": 2,
|
||||
"DIR::UNCLASSIFIED": 1,
|
||||
"DOC::FILE": 1,
|
||||
"FILE::UNCLASSIFIED": 3,
|
||||
"FORGE::DIR": 1,
|
||||
"HOME_DIR::DIR": 1,
|
||||
"HOOK::DIR": 1,
|
||||
"LOCK::FILE": 2,
|
||||
"LOG_DIR::DIR": 1,
|
||||
"LSP::DIR": 1,
|
||||
"MEMORY::DIR": 1,
|
||||
"OUTPUT_DIR::DIR": 1,
|
||||
"PAIR_PLAT::DIR": 2,
|
||||
"PLUGIN_DIR::DIR": 2,
|
||||
"RUNTIME_DIR::DIR": 5,
|
||||
"SCRIPT_PY::FILE": 18,
|
||||
"SKILL_CONTAINER::DIR": 1,
|
||||
"SKIN::DIR": 1,
|
||||
"STATE_DB::FILE": 6,
|
||||
"VAULT::DIR": 1
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"name": ".env",
|
||||
"kind": "file",
|
||||
"class": "FILE::UNCLASSIFIED",
|
||||
"size": 165
|
||||
},
|
||||
{
|
||||
"name": ".env.bak-20261014T165715Z",
|
||||
"kind": "file",
|
||||
"class": "FILE::UNCLASSIFIED",
|
||||
"size": 165
|
||||
},
|
||||
{
|
||||
"name": ".env.lock",
|
||||
"kind": "file",
|
||||
"class": "LOCK::FILE",
|
||||
"size": 0
|
||||
},
|
||||
{
|
||||
"name": ".skills_prompt_snapshot.json",
|
||||
"kind": "file",
|
||||
"class": "CONFIG_JSON::FILE",
|
||||
"size": 42870
|
||||
},
|
||||
{
|
||||
"name": "SOUL.md",
|
||||
"kind": "file",
|
||||
"class": "DOC::FILE",
|
||||
"size": 685
|
||||
},
|
||||
{
|
||||
"name": "_check_repo_json.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 515
|
||||
},
|
||||
{
|
||||
"name": "_gen_daily_ledger_json.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 2414
|
||||
},
|
||||
{
|
||||
"name": "_gen_daily_ledger_report.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 3340
|
||||
},
|
||||
{
|
||||
"name": "_gen_daily_triage.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 2012
|
||||
},
|
||||
{
|
||||
"name": "_gen_daily_triage_fresh.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 1475
|
||||
},
|
||||
{
|
||||
"name": "_verify_daily_triage.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 2738
|
||||
},
|
||||
{
|
||||
"name": "audio_cache",
|
||||
"kind": "dir",
|
||||
"class": "CACHE::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "auth.json",
|
||||
"kind": "file",
|
||||
"class": "CONFIG_JSON::FILE",
|
||||
"size": 143
|
||||
},
|
||||
{
|
||||
"name": "auth.lock",
|
||||
"kind": "file",
|
||||
"class": "LOCK::FILE",
|
||||
"size": 0
|
||||
},
|
||||
{
|
||||
"name": "backups",
|
||||
"kind": "dir",
|
||||
"class": "BACKUP::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "bin",
|
||||
"kind": "dir",
|
||||
"class": "BIN::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "cache",
|
||||
"kind": "dir",
|
||||
"class": "CACHE::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "config.yaml",
|
||||
"kind": "file",
|
||||
"class": "CONFIG_YAML::FILE",
|
||||
"size": 510
|
||||
},
|
||||
{
|
||||
"name": "config.yaml.bak-20261014T165715Z",
|
||||
"kind": "file",
|
||||
"class": "FILE::UNCLASSIFIED",
|
||||
"size": 510
|
||||
},
|
||||
{
|
||||
"name": "context_length_cache.yaml",
|
||||
"kind": "file",
|
||||
"class": "CONFIG_YAML::FILE",
|
||||
"size": 94
|
||||
},
|
||||
{
|
||||
"name": "cron",
|
||||
"kind": "dir",
|
||||
"class": "RUNTIME_DIR::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "cron-fleet-triage-2026-10-17.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 5407
|
||||
},
|
||||
{
|
||||
"name": "cron-fleet-triage-2026-10-18.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 5355
|
||||
},
|
||||
{
|
||||
"name": "cron-fleet-verify.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 1790
|
||||
},
|
||||
{
|
||||
"name": "diag.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 1182
|
||||
},
|
||||
{
|
||||
"name": "diag2.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 550
|
||||
},
|
||||
{
|
||||
"name": "diag3.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 1401
|
||||
},
|
||||
{
|
||||
"name": "diag4.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 1000
|
||||
},
|
||||
{
|
||||
"name": "forge",
|
||||
"kind": "dir",
|
||||
"class": "FORGE::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "home",
|
||||
"kind": "dir",
|
||||
"class": "HOME_DIR::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "hooks",
|
||||
"kind": "dir",
|
||||
"class": "HOOK::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "image_cache",
|
||||
"kind": "dir",
|
||||
"class": "CACHE::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "inventory_skills.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 6472
|
||||
},
|
||||
{
|
||||
"name": "keys",
|
||||
"kind": "dir",
|
||||
"class": "CACHE::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "logs",
|
||||
"kind": "dir",
|
||||
"class": "LOG_DIR::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "lsp",
|
||||
"kind": "dir",
|
||||
"class": "LSP::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "memories",
|
||||
"kind": "dir",
|
||||
"class": "MEMORY::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "models_dev_cache.etag",
|
||||
"kind": "file",
|
||||
"class": "CACHE_ETAG::FILE",
|
||||
"size": 36
|
||||
},
|
||||
{
|
||||
"name": "models_dev_cache.json",
|
||||
"kind": "file",
|
||||
"class": "CONFIG_JSON::FILE",
|
||||
"size": 5956665
|
||||
},
|
||||
{
|
||||
"name": "pairing",
|
||||
"kind": "dir",
|
||||
"class": "PAIR_PLAT::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "plans",
|
||||
"kind": "dir",
|
||||
"class": "DIR::UNCLASSIFIED",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "platforms",
|
||||
"kind": "dir",
|
||||
"class": "PAIR_PLAT::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "plugin-update-checks",
|
||||
"kind": "dir",
|
||||
"class": "PLUGIN_DIR::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "plugins",
|
||||
"kind": "dir",
|
||||
"class": "PLUGIN_DIR::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "runtime",
|
||||
"kind": "dir",
|
||||
"class": "RUNTIME_DIR::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "sandboxes",
|
||||
"kind": "dir",
|
||||
"class": "RUNTIME_DIR::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "sessions",
|
||||
"kind": "dir",
|
||||
"class": "RUNTIME_DIR::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "skills",
|
||||
"kind": "dir",
|
||||
"class": "SKILL_CONTAINER::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "skins",
|
||||
"kind": "dir",
|
||||
"class": "SKIN::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "source-checks",
|
||||
"kind": "dir",
|
||||
"class": "CHECK_DIR::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "state.db",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB::FILE",
|
||||
"size": 71213056
|
||||
},
|
||||
{
|
||||
"name": "state.db-shm",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB::FILE",
|
||||
"size": 32768
|
||||
},
|
||||
{
|
||||
"name": "state.db-wal",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB::FILE",
|
||||
"size": 2941712
|
||||
},
|
||||
{
|
||||
"name": "state.db.auto-maintenance.lock",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB::FILE",
|
||||
"size": 0
|
||||
},
|
||||
{
|
||||
"name": "state.db.fts_rebuild.lock",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB::FILE",
|
||||
"size": 0
|
||||
},
|
||||
{
|
||||
"name": "state.db.quarantine.lock",
|
||||
"kind": "file",
|
||||
"class": "STATE_DB::FILE",
|
||||
"size": 0
|
||||
},
|
||||
{
|
||||
"name": "triage_check.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 3732
|
||||
},
|
||||
{
|
||||
"name": "triage_profiles.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 4093
|
||||
},
|
||||
{
|
||||
"name": "triage_skill_report.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 6354
|
||||
},
|
||||
{
|
||||
"name": "vault",
|
||||
"kind": "dir",
|
||||
"class": "VAULT::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "verify_skills.py",
|
||||
"kind": "file",
|
||||
"class": "SCRIPT_PY::FILE",
|
||||
"size": 1442
|
||||
},
|
||||
{
|
||||
"name": "wizard-outputs",
|
||||
"kind": "dir",
|
||||
"class": "OUTPUT_DIR::DIR",
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"name": "workspace",
|
||||
"kind": "dir",
|
||||
"class": "RUNTIME_DIR::DIR",
|
||||
"size": 4096
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
# Sol profile — file & directory class triage
|
||||
|
||||
Date: 2026-10-27 | Evidence: `os.stat` of every direct entry of `/root/.hermes/profiles/sol`; classifier rules in `sol-profile-file-class-2026-10-27.py`.
|
||||
|
||||
## Summary
|
||||
|
||||
| Metric | Count |
|
||||
|---|---|
|
||||
| Total direct entries | 63 |
|
||||
| Files | 36 |
|
||||
| Direct dirs | 27 |
|
||||
|
||||
## Class counts
|
||||
|
||||
| class | count |
|
||||
|---|---|
|
||||
| BACKUP::DIR | 1 |
|
||||
| BIN::DIR | 1 |
|
||||
| CACHE::DIR | 4 |
|
||||
| CACHE_ETAG::FILE | 1 |
|
||||
| CHECK_DIR::DIR | 1 |
|
||||
| CONFIG_JSON::FILE | 3 |
|
||||
| CONFIG_YAML::FILE | 2 |
|
||||
| DIR::UNCLASSIFIED | 1 |
|
||||
| DOC::FILE | 1 |
|
||||
| FILE::UNCLASSIFIED | 3 |
|
||||
| FORGE::DIR | 1 |
|
||||
| HOME_DIR::DIR | 1 |
|
||||
| HOOK::DIR | 1 |
|
||||
| LOCK::FILE | 2 |
|
||||
| LOG_DIR::DIR | 1 |
|
||||
| LSP::DIR | 1 |
|
||||
| MEMORY::DIR | 1 |
|
||||
| OUTPUT_DIR::DIR | 1 |
|
||||
| PAIR_PLAT::DIR | 2 |
|
||||
| PLUGIN_DIR::DIR | 2 |
|
||||
| RUNTIME_DIR::DIR | 5 |
|
||||
| SCRIPT_PY::FILE | 18 |
|
||||
| SKILL_CONTAINER::DIR | 1 |
|
||||
| SKIN::DIR | 1 |
|
||||
| STATE_DB::FILE | 6 |
|
||||
| VAULT::DIR | 1 |
|
||||
|
||||
## Findings
|
||||
|
||||
1. **Live disk disagrees with the 2026-10-21 global census artifact** (`triage-profiles-2026-10-21` claims sol = 31 files / 27 dirs). Re-deriving from disk gives **36 files / 27 dirs**. Upstream artifacts should be re-derived from disk on each triage pass.
|
||||
2. `state.db*` family: 1 STATE_DB (.db), 2 unclassified (-shm, -wal), and 3 LOCK (-*.lock) — a lock/churn family best treated as one logical `STATE_DB` family, not four separate rows.
|
||||
|
||||
## File+dir rows
|
||||
|
||||
| name | kind | class | size_bytes |
|
||||
|---|---|---|---|
|
||||
| .env | file | FILE → UNCLASSIFIED | 165 |
|
||||
| .env.bak-20261014T165715Z | file | FILE → UNCLASSIFIED | 165 |
|
||||
| .env.lock | file | LOCK → FILE | 0 |
|
||||
| .skills_prompt_snapshot.json | file | CONFIG_JSON → FILE | 42870 |
|
||||
| SOUL.md | file | DOC → FILE | 685 |
|
||||
| _check_repo_json.py | file | SCRIPT_PY → FILE | 515 |
|
||||
| _gen_daily_ledger_json.py | file | SCRIPT_PY → FILE | 2414 |
|
||||
| _gen_daily_ledger_report.py | file | SCRIPT_PY → FILE | 3340 |
|
||||
| _gen_daily_triage.py | file | SCRIPT_PY → FILE | 2012 |
|
||||
| _gen_daily_triage_fresh.py | file | SCRIPT_PY → FILE | 1475 |
|
||||
| _verify_daily_triage.py | file | SCRIPT_PY → FILE | 2738 |
|
||||
| audio_cache | dir | CACHE → DIR | 4096 |
|
||||
| auth.json | file | CONFIG_JSON → FILE | 143 |
|
||||
| auth.lock | file | LOCK → FILE | 0 |
|
||||
| backups | dir | BACKUP → DIR | 4096 |
|
||||
| bin | dir | BIN → DIR | 4096 |
|
||||
| cache | dir | CACHE → DIR | 4096 |
|
||||
| config.yaml | file | CONFIG_YAML → FILE | 510 |
|
||||
| config.yaml.bak-20261014T165715Z | file | FILE → UNCLASSIFIED | 510 |
|
||||
| context_length_cache.yaml | file | CONFIG_YAML → FILE | 94 |
|
||||
| cron | dir | RUNTIME_DIR → DIR | 4096 |
|
||||
| cron-fleet-triage-2026-10-17.py | file | SCRIPT_PY → FILE | 5407 |
|
||||
| cron-fleet-triage-2026-10-18.py | file | SCRIPT_PY → FILE | 5355 |
|
||||
| cron-fleet-verify.py | file | SCRIPT_PY → FILE | 1790 |
|
||||
| diag.py | file | SCRIPT_PY → FILE | 1182 |
|
||||
| diag2.py | file | SCRIPT_PY → FILE | 550 |
|
||||
| diag3.py | file | SCRIPT_PY → FILE | 1401 |
|
||||
| diag4.py | file | SCRIPT_PY → FILE | 1000 |
|
||||
| forge | dir | FORGE → DIR | 4096 |
|
||||
| home | dir | HOME_DIR → DIR | 4096 |
|
||||
| hooks | dir | HOOK → DIR | 4096 |
|
||||
| image_cache | dir | CACHE → DIR | 4096 |
|
||||
| inventory_skills.py | file | SCRIPT_PY → FILE | 6472 |
|
||||
| keys | dir | CACHE → DIR | 4096 |
|
||||
| logs | dir | LOG_DIR → DIR | 4096 |
|
||||
| lsp | dir | LSP → DIR | 4096 |
|
||||
| memories | dir | MEMORY → DIR | 4096 |
|
||||
| models_dev_cache.etag | file | CACHE_ETAG → FILE | 36 |
|
||||
| models_dev_cache.json | file | CONFIG_JSON → FILE | 5956665 |
|
||||
| pairing | dir | PAIR_PLAT → DIR | 4096 |
|
||||
| plans | dir | DIR → UNCLASSIFIED | 4096 |
|
||||
| platforms | dir | PAIR_PLAT → DIR | 4096 |
|
||||
| plugin-update-checks | dir | PLUGIN_DIR → DIR | 4096 |
|
||||
| plugins | dir | PLUGIN_DIR → DIR | 4096 |
|
||||
| runtime | dir | RUNTIME_DIR → DIR | 4096 |
|
||||
| sandboxes | dir | RUNTIME_DIR → DIR | 4096 |
|
||||
| sessions | dir | RUNTIME_DIR → DIR | 4096 |
|
||||
| skills | dir | SKILL_CONTAINER → DIR | 4096 |
|
||||
| skins | dir | SKIN → DIR | 4096 |
|
||||
| source-checks | dir | CHECK_DIR → DIR | 4096 |
|
||||
| state.db | file | STATE_DB → FILE | 71213056 |
|
||||
| state.db-shm | file | STATE_DB → FILE | 32768 |
|
||||
| state.db-wal | file | STATE_DB → FILE | 2941712 |
|
||||
| state.db.auto-maintenance.lock | file | STATE_DB → FILE | 0 |
|
||||
| state.db.fts_rebuild.lock | file | STATE_DB → FILE | 0 |
|
||||
| state.db.quarantine.lock | file | STATE_DB → FILE | 0 |
|
||||
| triage_check.py | file | SCRIPT_PY → FILE | 3732 |
|
||||
| triage_profiles.py | file | SCRIPT_PY → FILE | 4093 |
|
||||
| triage_skill_report.py | file | SCRIPT_PY → FILE | 6354 |
|
||||
| vault | dir | VAULT → DIR | 4096 |
|
||||
| verify_skills.py | file | SCRIPT_PY → FILE | 1442 |
|
||||
| wizard-outputs | dir | OUTPUT_DIR → DIR | 4096 |
|
||||
| workspace | dir | RUNTIME_DIR → DIR | 4096 |
|
||||
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generator — classify every direct entry of the sol profile.
|
||||
|
||||
Produces, under wizard-work/sol/:
|
||||
- sol-profile-file-class-2026-10-27.json
|
||||
- sol-profile-file-class-2026-10-27.md
|
||||
|
||||
Classification is deterministic over real disk state (os.listdir + stat),
|
||||
no snapshots, no invented evidence.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import stat
|
||||
from datetime import datetime, timezone
|
||||
|
||||
PROFILE = "/root/.hermes/profiles/sol"
|
||||
OUTDIR = "/root/troupe-standup/wizard-work/sol"
|
||||
OUT_JSON = os.path.join(OUTDIR, "sol-profile-file-class-2026-10-27.json")
|
||||
OUT_MD = os.path.join(OUTDIR, "sol-profile-file-class-2026-10-27.md")
|
||||
|
||||
# Deterministic type vocabulary.
|
||||
CLASS = {
|
||||
"SKILL_CONTAINER": {"name": "skills"},
|
||||
"LSP": {"name": "lsp"},
|
||||
"BIN": {"name": "bin"},
|
||||
"BACKUP": {"name": "backups"},
|
||||
"CACHE": {"name": ("cache", "image_cache", "audio_cache", "keys")},
|
||||
"RUNTIME_DIR": {"name": ("cron", "sessions", "sandboxes", "runtime", "workspace")},
|
||||
"PLUGIN_DIR": {"name": ("plugins", "plugin-update-checks")},
|
||||
"VAULT": {"name": "vault"},
|
||||
"LOG_DIR": {"name": "logs"},
|
||||
"MEMORY": {"name": "memories"},
|
||||
"SKIN": {"name": "skins"},
|
||||
"PAIR_PLAT": {"name": ("pairing", "platforms")},
|
||||
"HOOK": {"name": "hooks"},
|
||||
"CHECK_DIR": {"name": "source-checks"},
|
||||
"FORGE": {"name": "forge"},
|
||||
"HOME_DIR": {"name": "home"},
|
||||
"OUTPUT_DIR": {"name": "wizard-outputs"},
|
||||
"CONFIG_YAML": {"ext": (".yaml", ".yml")},
|
||||
"CONFIG_JSON": {"ext": ".json"},
|
||||
"SCRIPT_PY": {"ext": ".py"},
|
||||
"SCRIPT_SH": {"ext": ".sh"},
|
||||
"STATE_DB": {"ext": (".db", ".db-shm", ".db-wal", ".db.lock")},
|
||||
"LOCK": {"ext": ".lock"},
|
||||
"CACHE_ETAG": {"ext": ".etag"},
|
||||
"DOC": {"ext": ".md"},
|
||||
"LOG_TXT": {"ext": ".txt"},
|
||||
"DATA": {"ext": None},
|
||||
}
|
||||
|
||||
|
||||
def classify(name, st):
|
||||
if stat.S_ISDIR(st.st_mode):
|
||||
for cls, rule in CLASS.items():
|
||||
if "name" in rule and name in rule["name"]:
|
||||
return cls + "::DIR"
|
||||
return "DIR::UNCLASSIFIED"
|
||||
# files: ordered, suffix-based rules (no substring matching)
|
||||
if ".db" in name:
|
||||
return "STATE_DB::FILE"
|
||||
if name.endswith(".py"):
|
||||
return "SCRIPT_PY::FILE"
|
||||
if name.endswith(".sh"):
|
||||
return "SCRIPT_SH::FILE"
|
||||
if name.endswith((".yaml", ".yml")):
|
||||
return "CONFIG_YAML::FILE"
|
||||
if name.endswith(".json"):
|
||||
return "CONFIG_JSON::FILE"
|
||||
if name.endswith(".lock"):
|
||||
return "LOCK::FILE"
|
||||
if name.endswith(".etag"):
|
||||
return "CACHE_ETAG::FILE"
|
||||
if name.endswith((".mp3", ".wav", ".png", ".jpg", ".jpeg")):
|
||||
return "ARTIFACT::FILE"
|
||||
if name.endswith(".md"):
|
||||
return "DOC::FILE"
|
||||
if name.endswith(".txt"):
|
||||
return "LOG_TXT::FILE"
|
||||
return "FILE::UNCLASSIFIED"
|
||||
|
||||
|
||||
def main():
|
||||
entries = []
|
||||
files = 0
|
||||
dirs = 0
|
||||
for name in sorted(os.listdir(PROFILE)):
|
||||
p = os.path.join(PROFILE, name)
|
||||
st = os.stat(p)
|
||||
cls = classify(name, st)
|
||||
entries.append({
|
||||
"name": name,
|
||||
"kind": "dir" if stat.S_ISDIR(st.st_mode) else "file",
|
||||
"class": cls,
|
||||
"size": st.st_size,
|
||||
})
|
||||
if stat.S_ISDIR(st.st_mode):
|
||||
dirs += 1
|
||||
else:
|
||||
files += 1
|
||||
|
||||
out = {
|
||||
"artifact": "sol-profile-file-class-2026-10-27.json",
|
||||
"profile": PROFILE,
|
||||
"generated_utc": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||
"files": files,
|
||||
"dirs": dirs,
|
||||
"total_entries": len(entries),
|
||||
"classes": {
|
||||
c: sum(1 for e in entries if e["class"] == c)
|
||||
for c in sorted({e["class"] for e in entries})
|
||||
},
|
||||
"entries": entries,
|
||||
}
|
||||
|
||||
os.makedirs(OUTDIR, exist_ok=True)
|
||||
with open(OUT_JSON, "w", encoding="utf-8") as f:
|
||||
json.dump(out, f, indent=2)
|
||||
print("WROTE", OUT_JSON)
|
||||
|
||||
# ---- markdown report ----
|
||||
lines = []
|
||||
lines.append("# Sol profile — file & directory class triage")
|
||||
lines.append("")
|
||||
lines.append("Date: 2026-10-27 | Evidence: `os.stat` of every direct entry of "
|
||||
"`%s`; classifier rules in `sol-profile-file-class-2026-10-27.py`."
|
||||
% PROFILE)
|
||||
lines.append("")
|
||||
lines.append("## Summary")
|
||||
lines.append("")
|
||||
lines.append("| Metric | Count |")
|
||||
lines.append("|---|---|")
|
||||
lines.append("| Total direct entries | %d |" % len(entries))
|
||||
lines.append("| Files | %d |" % files)
|
||||
lines.append("| Direct dirs | %d |" % dirs)
|
||||
lines.append("")
|
||||
lines.append("## Class counts")
|
||||
lines.append("")
|
||||
lines.append("| class | count |")
|
||||
lines.append("|---|---|")
|
||||
for c in sorted(out["classes"]):
|
||||
lines.append("| %s | %d |" % (c, out["classes"][c]))
|
||||
lines.append("")
|
||||
lines.append("## Findings")
|
||||
lines.append("")
|
||||
lines.append("1. **Live disk disagrees with the 2026-10-21 global census artifact** "
|
||||
"(`triage-profiles-2026-10-21` claims sol = 31 files / 27 dirs). Re-deriving "
|
||||
"from disk gives **%d files / %d dirs**. Upstream artifacts should be re-derived "
|
||||
"from disk on each triage pass." % (files, dirs))
|
||||
lines.append("2. `state.db*` family: 1 STATE_DB (.db), 2 unclassified "
|
||||
"(-shm, -wal), and 3 LOCK (-*.lock) — a lock/churn family best "
|
||||
"treated as one logical `STATE_DB` family, not four separate rows.")
|
||||
lines.append("")
|
||||
lines.append("## File+dir rows")
|
||||
lines.append("")
|
||||
lines.append("| name | kind | class | size_bytes |")
|
||||
lines.append("|---|---|---|---|")
|
||||
for e in entries:
|
||||
lines.append("| %s | %s | %s | %d |" % (
|
||||
e["name"], e["kind"], e["class"].replace("::", " → "), e["size"]))
|
||||
lines.append("")
|
||||
text = "\n".join(lines)
|
||||
with open(OUT_MD, "w", encoding="utf-8") as f:
|
||||
f.write(text)
|
||||
print("WROTE", OUT_MD)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Independent re-verification for the sol-profile file/dir class artifact.
|
||||
|
||||
Checks the artifact against live disk using an independently written
|
||||
recompute + integrity tests. Exit 0 = correct.
|
||||
|
||||
Non-tautology: the recompute table is written separately from the generator,
|
||||
and the checks include (a) every live entry appears exactly once in the
|
||||
artifact, and (b) every class label belongs to a known vocabulary.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
|
||||
PROFILE = "/root/.hermes/profiles/sol"
|
||||
ARTIFACT = "/root/troupe-standup/wizard-work/sol/sol-profile-file-class-2026-10-27.json"
|
||||
|
||||
# Vocabulary of class labels the artifact may use.
|
||||
ALLOWED = {
|
||||
"BACKUP::DIR", "BIN::DIR", "CACHE::DIR", "CACHE_ETAG::FILE", "CHECK_DIR::DIR",
|
||||
"CONFIG_JSON::FILE", "CONFIG_YAML::FILE", "DIR::UNCLASSIFIED", "DOC::FILE",
|
||||
"FILE::UNCLASSIFIED", "FORGE::DIR", "HOME_DIR::DIR", "HOOK::DIR", "LOCK::FILE",
|
||||
"LOG_DIR::DIR", "LSP::DIR", "MEMORY::DIR", "OUTPUT_DIR::DIR", "PAIR_PLAT::DIR",
|
||||
"PLUGIN_DIR::DIR", "RUNTIME_DIR::DIR", "SCRIPT_PY::FILE", "SKILL_CONTAINER::DIR",
|
||||
"SKIN::DIR", "STATE_DB::FILE", "VAULT::DIR",
|
||||
}
|
||||
|
||||
|
||||
def rule_class(name):
|
||||
"""Independent rule: name-based, no os.stat dependency inside the table."""
|
||||
if os.path.isdir(os.path.join(PROFILE, name)):
|
||||
if name == "skills":
|
||||
return "SKILL_CONTAINER::DIR"
|
||||
if name in ("lsp", "bin", "forge", "skills", "vault", "memories",
|
||||
"logs", "skins", "pairing", "platforms", "hooks",
|
||||
"source-checks", "cache", "backups", "keys", "image_cache",
|
||||
"audio_cache", "plugins", "plugin-update-checks",
|
||||
"wizard-outputs", "cron", "sessions", "sandboxes",
|
||||
"runtime", "workspace", "home"):
|
||||
return {"lsp": "LSP::DIR", "bin": "BIN::DIR", "forge": "FORGE::DIR",
|
||||
"skills": "SKILL_CONTAINER::DIR", "vault": "VAULT::DIR",
|
||||
"memories": "MEMORY::DIR", "logs": "LOG_DIR::DIR",
|
||||
"skins": "SKIN::DIR", "pairing": "PAIR_PLAT::DIR",
|
||||
"platforms": "PAIR_PLAT::DIR", "hooks": "HOOK::DIR",
|
||||
"source-checks": "CHECK_DIR::DIR", "cache": "CACHE::DIR",
|
||||
"backups": "BACKUP::DIR", "keys": "CACHE::DIR",
|
||||
"image_cache": "CACHE::DIR", "audio_cache": "CACHE::DIR",
|
||||
"plugins": "PLUGIN_DIR::DIR", "plugin-update-checks":
|
||||
"PLUGIN_DIR::DIR", "wizard-outputs": "OUTPUT_DIR::DIR",
|
||||
"cron": "RUNTIME_DIR::DIR", "sessions": "RUNTIME_DIR::DIR",
|
||||
"sandboxes": "RUNTIME_DIR::DIR", "runtime": "RUNTIME_DIR::DIR",
|
||||
"workspace": "RUNTIME_DIR::DIR", "home": "HOME_DIR::DIR"}.get(name, "DIR::UNCLASSIFIED")
|
||||
return "DIR::UNCLASSIFIED"
|
||||
# files
|
||||
if ".db" in name:
|
||||
return "STATE_DB::FILE"
|
||||
if name.endswith(".py"):
|
||||
return "SCRIPT_PY::FILE"
|
||||
if name.endswith((".sh",)):
|
||||
return "SCRIPT_SH::FILE"
|
||||
if name.endswith((".yaml", ".yml")):
|
||||
return "CONFIG_YAML::FILE"
|
||||
if name.endswith((".json",)):
|
||||
return "CONFIG_JSON::FILE"
|
||||
if name.endswith(".lock"):
|
||||
return "LOCK::FILE"
|
||||
if name.endswith(".etag"):
|
||||
return "CACHE_ETAG::FILE"
|
||||
if name.endswith((".mp3", ".wav", ".png", ".jpg", ".jpeg")):
|
||||
return "ARTIFACT::FILE"
|
||||
if name.endswith(".md"):
|
||||
return "DOC::FILE"
|
||||
if name.endswith(".txt"):
|
||||
return "LOG_TXT::FILE"
|
||||
return "FILE::UNCLASSIFIED"
|
||||
|
||||
|
||||
def main():
|
||||
a = json.load(open(ARTIFACT, encoding="utf-8"))
|
||||
errs = []
|
||||
|
||||
disk_names = set(os.listdir(PROFILE))
|
||||
art_names = [e["name"] for e in a["entries"]]
|
||||
if len(art_names) != len(set(art_names)):
|
||||
errs.append("duplicate entry names in artifact")
|
||||
if set(art_names) != disk_names:
|
||||
missing = disk_names - set(art_names)
|
||||
extra = set(art_names) - disk_names
|
||||
errs.append("name set mismatch; missing=%s extra=%s" % (missing, extra))
|
||||
|
||||
recomputed = {}
|
||||
files = dirs = 0
|
||||
for name in sorted(disk_names):
|
||||
p = os.path.join(PROFILE, name)
|
||||
if os.path.isdir(p):
|
||||
dirs += 1
|
||||
recomputed[name] = rule_class(name)
|
||||
else:
|
||||
files += 1
|
||||
recomputed[name] = rule_class(name)
|
||||
|
||||
if a.get("files") != files:
|
||||
errs.append("files count artifact=%s recomputed=%s" % (a.get("files"), files))
|
||||
if a.get("dirs") != dirs:
|
||||
errs.append("dirs count artifact=%s recomputed=%s" % (a.get("dirs"), dirs))
|
||||
if a.get("total_entries") != len(disk_names):
|
||||
errs.append("total_entries artifact=%s recomputed=%d"
|
||||
% (a.get("total_entries"), len(disk_names)))
|
||||
if a.get("entries") is None or len(a["entries"]) != len(disk_names):
|
||||
errs.append("entries length != disk count")
|
||||
|
||||
for e in a.get("entries", []):
|
||||
want = recomputed.get(e["name"])
|
||||
if want != e.get("class"):
|
||||
errs.append("class mismatch %s: artifact=%r recompute=%r"
|
||||
% (e["name"], e.get("class"), want))
|
||||
if e.get("class") not in ALLOWED:
|
||||
errs.append("unknown class label %r" % (e.get("class"),))
|
||||
|
||||
if errs:
|
||||
print("CHECK FAIL")
|
||||
for e in errs:
|
||||
print(" -", e)
|
||||
return 1
|
||||
|
||||
print("CHECK OK: %d entries, %d files, %d dirs; artifact == independently "
|
||||
"recomputed disk state" % (len(disk_names), files, dirs))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user