plugins/claude-code-hermit/skills/smoke-test/SKILL.md
Post-hatch validation — checks config, OPERATOR.md, plugin references, routines, and optionally sends a channel test message. Run after hatch to verify setup.
npx skillsauth add gtapps/claude-code-hermit smoke-testInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Validate the post-hatch setup. Produces a structured report with PASS/WARN/FAIL per check.
Track passed, warnings, failures counts. Collect output lines for the final report.
.claude-code-hermit/config.json
config.json missing or invalidconfig.json parsed${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json to get the current plugin versionconfig._hermit_versions["claude-code-hermit"] with the plugin version
version matches plugin (X.Y.Z)config version X.Y.Z != plugin X.Y.Z — run /claude-code-hermit:hermit-evolveagent_name, channels, env, heartbeat
missing required key: <key>.claude-code-hermit/OPERATOR.md exists
OPERATOR.md missing — run hatch or create manuallyOPERATOR.md is empty — fill in project context{{ placeholder patterns (NOT <!-- which are legitimate HTML comments)
OPERATOR.md contains unfilled {{ placeholdersOPERATOR.md readablescheduled_checks array from config.jsonskill field (formats accepted: /plugin:skill-name or plugin:skill-name)<plugin>:<skill-name> in the harness's available-skills list (the system-reminder enumerating loaded skills is authoritative — do NOT grep the plugin cache; cross-marketplace layouts make path checks unreliable)scheduled_checks[N]: <plugin>:<skill-name> loadedscheduled_checks[N]: <plugin>:<skill-name> not loaded — install the plugin or remove the entryRun: node ${CLAUDE_PLUGIN_ROOT}/scripts/cron-tz-shift.js "0 4 * * *" "UTC"
0 4 * * *: PASS cron-tz-shift helper availablecron-tz-shift helper missing or broken — run /hermit-evolveroutines array from config.jsonid, schedule, skill, enabled): FAIL per missing keytime or days keys are present: FAIL routine "<id>" uses legacy "time"/"days" — migrate to "schedule" (5-field cron)schedule is a 5-field cron expression (space-separated, 5 fields: min hour dom month dow): FAIL if malformedskill contains : (plugin:skill-name format): FAIL with expected formatroutine "<id>" valid (<schedule>, <skill>)Template defaults: ${CLAUDE_PLUGIN_ROOT}/state-templates/ — alert-state.json.template, micro-proposals.json.template.
For each file: parse JSON. If missing or unparseable, rewrite from the corresponding template. If parseable but wrong shape, repair in place — backfill missing keys from template defaults, overwrite keys that exist with the wrong type, preserve all other existing data. Emit one WARN per file that needed repair (noting what was fixed), or PASS if valid.
.claude-code-hermit/state/alert-state.json — object with: alerts (object), self_eval (object), total_ticks (number), last_digest_date (any, presence required)
alerts: {}, self_eval: {}, total_ticks: 0, last_digest_date: null) → WARN alert-state.json repaired: <keys>.claude-code-hermit/state/micro-proposals.json — object with pending key (array)
pending key (and active key present): migrate — read active value; if non-null, set pending: [<active value>]; if null, set pending: []; remove active key → WARN micro-proposals.json migrated: active → pendingpending key (and no active key): add "pending": [] → WARN micro-proposals.json missing pending key — backfilledpending is not an array: overwrite with [] → WARN micro-proposals.json pending is not an array — reset"Smoke test — channel is working." (include agent name if configured)<channel> test message sent<channel> test message failed: <error><channel> plugin not available for testpush_notifications from config.jsonfalse or absent: skip silentlytrue: call PushNotification(message="Smoke test: push fallback is wired.", status="proactive")
PushNotification test dispatched (visible: desktop if daemon running, mobile if Remote Control paired)PushNotification accepted but not delivered. Push will silently no-op until a notification daemon is running or Remote Control is paired.PushNotification test failed: <error> (likely a model/schema bug, surface for inspection)Output each check result as exactly one line:
PASS config.json parsed and version matches plugin (0.3.4)
WARN OPERATOR.md contains unfilled {{ placeholders
WARN scheduled_checks[0]: claude-code-setup:claude-automation-recommender not loaded — install the plugin or remove the entry
PASS routine "heartbeat-restart" valid (0 4 * * *, claude-code-hermit:heartbeat start)
PASS routine "morning" valid (0 9 * * *, claude-code-hermit:reflect)
FAIL routine "bad" uses legacy "time" field — migrate to "schedule" (5-field cron)
Summary line at end:
Smoke test: 4 passed, 1 warning, 1 failed
For each FAIL, include a remediation hint on the same line or the line after.
tools
Presence history & tracker-health report — current home/away state, reliability, recent arrival/departure transitions, and activity patterns for person/device_tracker entities. Use when the operator asks about presence history or when a presence-dependent automation (locks, alarm, vacuum, climate) misbehaves.
development
Evening house brief — end-of-day security check, device status, and energy snapshot. Runs as a daily routine at 22:30 or on demand.
tools
Browse and explain the hermit's Home Assistant automations — list by topic, filter by keyword with plain-language YAML explanations, or sort by last-fired. Read-only. Use when the operator asks "what automations do I have / what does this one do / which haven't fired."
tools
On-demand HA-voice brainstorm — reads entity inventory, automation/script listings, and operator intent to surface at most 2 capability-gap ideas, each gated by proposal-triage before becoming a PROP. Invoke when the operator asks "what automations am I missing?", "any coverage gaps?", or "brainstorm improvements". Never runs autonomously.