snippet.py: check_tools() imports hermes_tools and requires callable(getattr(...)); --require is the negative-control hook; HERMES_HOME/HERMES_PROFILE/--home/--profile resolve every path; rc 0/1/2. verify_hermes_setup.sh: HERE from $0, sibling snippet.py graded, --home/--root/--profile, VERDICT line, rc 0/1/2. New test_env_verifiers.py (14 black-box cells, stub hermes_tools on PYTHONPATH, synthetic trees) and CHECK-env-verifiers. Pre-repair blobs: 9 cells red for snippet.py, 6 for the shell script.
142 lines
4.1 KiB
Bash
Executable File
142 lines
4.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# Verify the directories a Hermes Agent profile ships into -- on the tree the
|
|
# script is run from, not on the host it was written on.
|
|
#
|
|
# Q109. This script used to test three absolute paths under the root user's
|
|
# home, so it printed its three ticks and "All critical paths verified" rc 0 on
|
|
# any tree, and it read nothing relative to itself. It now resolves
|
|
# - its own directory from $0 (so the sibling snippet.py it names is the one
|
|
# that shipped beside it, and a lone copy has no opinion to report), and
|
|
# - the profile home from --home, else $HERMES_HOME, else
|
|
# ~/.hermes/profiles/$HERMES_PROFILE (default profile: spark), with the
|
|
# Hermes root from --root, else the parent of the profile home's `profiles`
|
|
# directory, else the profile home's own parent,
|
|
# so the same invocation fails on a tree that is missing the paths it names.
|
|
#
|
|
# Exit codes follow the repo's tools/ contract:
|
|
# 0 = every required path exists
|
|
# 1 = a required path is missing (each is printed on its own MISSING: line)
|
|
# 2 = usage error, or the script's own directory could not be resolved
|
|
set -u
|
|
|
|
HERE=$(cd -- "$(dirname -- "$(readlink -f -- "$0")")" && pwd) || {
|
|
echo "could not resolve the script's own directory" >&2
|
|
exit 2
|
|
}
|
|
|
|
PROFILE=${HERMES_PROFILE:-spark}
|
|
HOME_ARG=""
|
|
ROOT_ARG=""
|
|
|
|
usage() {
|
|
cat <<'USAGE'
|
|
usage: verify_hermes_setup.sh [--home DIR] [--root DIR] [--profile NAME]
|
|
|
|
Grades one Hermes installation:
|
|
ROOT the Hermes root
|
|
HOME the profile home (ROOT/profiles/NAME, usually)
|
|
HOME/cache/scratch the profile's scratch directory
|
|
<script dir>/snippet.py the snippet that ships beside this script
|
|
|
|
Defaults: --home $HERMES_HOME or ~/.hermes/profiles/$HERMES_PROFILE;
|
|
--root derived from the profile home; --profile $HERMES_PROFILE or spark.
|
|
Exit 0 all present, 1 a required path is missing, 2 usage error.
|
|
USAGE
|
|
}
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
--home)
|
|
if [ "$#" -lt 2 ]; then echo "--home needs a value" >&2; exit 2; fi
|
|
HOME_ARG=$2
|
|
shift 2
|
|
;;
|
|
--root)
|
|
if [ "$#" -lt 2 ]; then echo "--root needs a value" >&2; exit 2; fi
|
|
ROOT_ARG=$2
|
|
shift 2
|
|
;;
|
|
--profile)
|
|
if [ "$#" -lt 2 ]; then echo "--profile needs a value" >&2; exit 2; fi
|
|
PROFILE=$2
|
|
shift 2
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "unknown argument: $1" >&2
|
|
usage >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ -z "$HOME_ARG" ]; then
|
|
if [ -n "${HERMES_HOME:-}" ]; then
|
|
HOME_ARG=$HERMES_HOME
|
|
else
|
|
HOME_ARG=$HOME/.hermes/profiles/$PROFILE
|
|
fi
|
|
fi
|
|
|
|
if [ -z "$ROOT_ARG" ]; then
|
|
if [ -n "${HERMES_ROOT:-}" ]; then
|
|
ROOT_ARG=$HERMES_ROOT
|
|
else
|
|
parent=$(dirname -- "$HOME_ARG")
|
|
if [ "$(basename -- "$parent")" = "profiles" ]; then
|
|
ROOT_ARG=$(dirname -- "$parent")
|
|
else
|
|
ROOT_ARG=$parent
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo "=== Hermes Agent Profile Verification ==="
|
|
echo "script dir: $HERE"
|
|
echo "hermes root: $ROOT_ARG"
|
|
echo "profile home: $HOME_ARG"
|
|
echo "profile: $PROFILE"
|
|
|
|
missing=0
|
|
for path in "$ROOT_ARG" "$HOME_ARG" "$HOME_ARG/cache/scratch" "$HERE/snippet.py"; do
|
|
if [ -e "$path" ]; then
|
|
echo "ok: $path"
|
|
else
|
|
echo "MISSING: $path"
|
|
missing=$((missing + 1))
|
|
fi
|
|
done
|
|
|
|
# Advisory: this lane does not depend on these, so a miss is a note.
|
|
for path in "$ROOT_ARG/skills" "$ROOT_ARG/plugins"; do
|
|
if [ -d "$path" ]; then
|
|
echo "ok (optional): $path"
|
|
else
|
|
echo "note: optional path absent: $path"
|
|
fi
|
|
done
|
|
|
|
if command -v hermes >/dev/null 2>&1; then
|
|
echo "note: hermes CLI on PATH: $(command -v hermes)"
|
|
else
|
|
echo "note: hermes CLI not on PATH"
|
|
fi
|
|
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
echo "note: python3: $(python3 --version 2>&1)"
|
|
else
|
|
echo "MISSING: python3 (snippet.py cannot be run)"
|
|
missing=$((missing + 1))
|
|
fi
|
|
|
|
echo ""
|
|
if [ "$missing" -gt 0 ]; then
|
|
echo "VERDICT: FAIL ($missing required path(s) missing)"
|
|
exit 1
|
|
fi
|
|
echo "VERDICT: PASS"
|
|
exit 0
|