(a) import-resolve: 9 OUTSIDE_REPO faults -> 0 over 138 graded files. The eight
lanes' test files now insert str(Path(__file__).resolve().parent) and resolve
their data paths from __file__; test_hermes.py is rewritten as the host probe it
always was (skills root from HERMES_SKILLS_DIR/HERMES_HOME/~/.hermes/skills, rc 0
found / 77 SKIP / 1 FAIL) instead of binding a module that does not exist.
Falsified: poisoning the repo copy reds the rebound test (rc 1) and leaves HEAD's
host-bound copy green (rc 0), both restored.
(b) path-claims: 225 new -> 0. All 225 came from sol's untracked-file census; each
was measured (0 add-commits on any ref, present on disk untracked, listed verbatim
in the census) and is a NOT_ADDED row under a batch note. One CLEARED row dropped
(spark/lwc_counter.py, resurrected at 3e667eb after Q125 retired it).
Carried in, not authored here: tools/verify.py's ninth leg and the two-line Q98
record (Sentinel's Q98 artifact), so HEAD agrees with Q98's own text.
verify --repo .: 9 legs, 9 pass, 0 fault -- gate OK. Report:
/root/.hermes/wizard-outputs/volt/2026-10-30-q126.md
98 lines
3.4 KiB
Python
98 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Verify the hermes-agent skill is present and readable on this host.
|
|
|
|
This is a HOST probe, not a repo test: its subject -- the live Hermes skill
|
|
catalog -- lives outside this tree, so it binds no module from it. The skills
|
|
root is taken from HERMES_SKILLS_DIR, else HERMES_HOME, else ~/.hermes/skills;
|
|
it is never a pinned /root path, so a copy of this file grades the host it is
|
|
run on.
|
|
|
|
Exit codes, because "not run" must never read as "verified":
|
|
0 the skill's SKILL.md was found and its YAML frontmatter parsed with
|
|
name: hermes-agent and a non-empty description
|
|
77 SKIP -- this host carries no Hermes skills root, so nothing was measured
|
|
1 FAIL -- the root exists but the skill is missing, or its frontmatter is
|
|
unusable
|
|
"""
|
|
import os
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
SKIP = 77
|
|
|
|
|
|
def skills_root():
|
|
"""The catalog this host actually carries, resolved per run."""
|
|
explicit = os.environ.get("HERMES_SKILLS_DIR")
|
|
if explicit:
|
|
return Path(explicit).expanduser()
|
|
home = os.environ.get("HERMES_HOME")
|
|
return (Path(home).expanduser() if home else Path.home() / ".hermes") / "skills"
|
|
|
|
|
|
def find_skill_md(root, name):
|
|
"""Every SKILL.md under a directory called `name`, nearest the root first."""
|
|
direct = root / name / "SKILL.md"
|
|
hits = [direct] if direct.is_file() else []
|
|
hits.extend(sorted(root.glob("**/%s/SKILL.md" % name)))
|
|
return [h for h in hits if h.is_file()]
|
|
|
|
|
|
def frontmatter(text):
|
|
"""The fenced `---` block's `key: value` pairs, or None when there is none."""
|
|
m = re.match(r"---\r?\n(.*?)\r?\n---\r?\n", text, re.S)
|
|
if not m:
|
|
return None
|
|
out = {}
|
|
for line in m.group(1).splitlines():
|
|
if ":" not in line or line.lstrip().startswith("#"):
|
|
continue
|
|
key, val = line.split(":", 1)
|
|
out[key.strip()] = val.strip().strip('"').strip("'")
|
|
return out
|
|
|
|
|
|
def main():
|
|
root = skills_root()
|
|
print("skills root: %s" % root)
|
|
if not root.is_dir():
|
|
print("SKIP: no Hermes skills root at %s -- nothing was measured" % root)
|
|
return SKIP
|
|
|
|
hits = find_skill_md(root, "hermes-agent")
|
|
if not hits:
|
|
print("FAIL: the root exists but carries no hermes-agent/SKILL.md")
|
|
many = sorted(p.name for p in root.iterdir() if p.is_dir())
|
|
print("directories under the root: %s" % (many[:10] or "none"))
|
|
return 1
|
|
|
|
for path in hits:
|
|
try:
|
|
text = path.read_text(encoding="utf-8")
|
|
except (OSError, UnicodeDecodeError) as exc:
|
|
print("FAIL: cannot read %s: %s" % (path, exc))
|
|
return 1
|
|
fm = frontmatter(text)
|
|
if fm is None:
|
|
print("FAIL: %s has no fenced frontmatter block" % path)
|
|
return 1
|
|
if fm.get("name") != "hermes-agent":
|
|
print("FAIL: %s declares name %r, want 'hermes-agent'"
|
|
% (path, fm.get("name")))
|
|
return 1
|
|
if not fm.get("description"):
|
|
print("FAIL: %s declares no description" % path)
|
|
return 1
|
|
print("PASS: %s" % path)
|
|
print(" name=%s version=%s" % (fm.get("name"), fm.get("version", "?")))
|
|
print(" description=%s" % fm["description"][:70])
|
|
|
|
print("\nAll checks passed - hermes-agent skill is present and readable (%d file(s))"
|
|
% len(hits))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|