plugins/claude-code-hermit/skills/reflect-scheduled-checks/SKILL.md
Standalone routine skill for interval-triggered scheduled checks. Runs one due check, gates findings through reflection-judge + proposal-triage, applies state, and logs. Run as a daily routine — not called by reflect.
npx skillsauth add gtapps/claude-code-hermit reflect-scheduled-checksInstall 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.
Standalone routine skill. Runs at most one due interval-triggered scheduled check per invocation, gates any findings through the normal proposal pipeline, applies state, and appends a Progress Log entry. Invoked by the scheduled-checks routine (daily, offset from reflect).
Any skill registered in config.scheduled_checks that satisfies this contract:
scheduled_checks.interval_days.Read config.json → scheduled_checks (filter to enabled: true, trigger: "interval").
Read state/reflection-state.json → scheduled_checks (per-check state: last_run, last_unavailable_at, last_error_at, consecutive_empty).
From the enabled interval entries, keep those where:
last_run is null or older than interval_days days, ANDlast_unavailable_at is null or older than 4 hours (transient cooldown — skill may have been briefly unavailable), ANDlast_error_at is null or older than interval_days days (persistent back-off for true errors)Select the entry with the oldest last_run (null sorts first). If none are due, skip to the Progress Log (§ 7) with outcome skipped.
Invoke the skill command string as-is, using the Skill tool. Do not "verify installation" first — the harness's loaded-skills list (shown in system-reminders) is authoritative. In particular, never grep ~/.claude/plugins/cache/ or any plugin directory to check whether a plugin is installed — the cache layout is cache/<marketplace>/<plugin>/, not cache/<plugin>/, and assumption-based path checks have produced false-negative unavailable outcomes.
Classify the result:
Skill tool rejects it as unknown → outcome: unavailableoutcome: erroroutcome: actionable, summarize findingoutcome: contextual, summarize finding; apply directly if trivialoutcome: emptyactionable / contextual:
Pass through the Evidence Validation gate:
Candidate: <title derived from finding>
Tier: 1
Evidence Source: scheduled-check/<id>
Evidence: <one-paragraph summary>
Sessions: none
Delegate to claude-code-hermit:reflection-judge. On ACCEPT (scheduled-check) or DOWNGRADE, proceed to claude-code-hermit:proposal-triage with:
Title: <title>
Evidence Source: scheduled-check/<id>
Evidence: <summary>
Parse line 1 as the verdict. Lines 2+ are additive metadata (closest_prop, aligned, operator_excerpt, overlap_compiled, prior_discussion, failed_condition) — read for context if useful but do not branch on them.
After receiving the verdict, append one event to state/proposal-metrics.jsonl:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/append-metrics.ts \
.claude-code-hermit/state/proposal-metrics.jsonl \
'{"ts":"<now ISO>","type":"triage-verdict","verdict":"<CREATE|SUPPRESS|DUPLICATE>","caller":"scheduled-checks"}'
CREATE → classify tier. Tier 1/2: queue micro-approval (§ Micro-approval queuing). Tier 3: call /claude-code-hermit:proposal-create directly.SUPPRESS or DUPLICATE → drop silently; note in SHELL.md Progress Log.On SUPPRESS from reflection-judge → drop silently.
empty:
No proposal candidate. Increment consecutive_empty counter in state (§ State update). Check interval-adjustment logic (§ Interval adjustment proposals).
unavailable:
Note in SHELL.md ## Findings: Scheduled check skipped: <id> — skill unavailable (cooldown 4h). No candidate.
error:
Note in SHELL.md ## Findings: Scheduled check error: <id> — retrying after interval_days. No candidate.
skipped: No action except Progress Log.
Every micro-proposal question must include: [observed pattern + duration] + [consequence] + [exact proposed change] + "Yes / No"
Queuing procedure:
MP-YYYYMMDD-N where N increments within the same day (0, 1, 2). Check existing micro-queued events in proposal-metrics.jsonl for today to determine N.micro-queued event to proposal-metrics.jsonl first (so a partial failure leaves a recoverable orphaned event, not a silent ghost entry):
bun ${CLAUDE_PLUGIN_ROOT}/scripts/append-metrics.ts \
.claude-code-hermit/state/proposal-metrics.jsonl \
'{"ts":"<now ISO>","type":"micro-queued","micro_id":"MP-YYYYMMDD-N","tier":1,"question":"<full question text>"}'
state/micro-proposals.json. Append a new entry to pending with id: "MP-YYYYMMDD-N", tier: <1|2>, status: "pending", follow_up_count: 0, ts: "<now ISO>", question: "<full question text>". Write the file.Using the current consecutive_empty value (after update in § State update):
Reset rules:
empty outcome → consecutive_empty += 1actionable / contextual outcome → consecutive_empty = 0Proposals (standard Three-Condition Rule, not tagged scheduled-check):
interval_days (e.g., 7 → 14). Three occurrences = repeated pattern; high interval_days means the check never fires usefully = meaningful consequence; operator approves the config change = actionable. Pass through claude-code-hermit:proposal-triage before creating.Adjustments always go through PROP-NNN — this skill never auto-adjusts.
Write the state delta directly to state/reflection-state.json → scheduled_checks.<id>:
bun -e "
const fs=require('fs');
const f='.claude-code-hermit/state/reflection-state.json';
try {
const s=JSON.parse(fs.readFileSync(f,'utf-8'));
if(!s.scheduled_checks) s.scheduled_checks={};
const id='<check-id>';
if(!s.scheduled_checks[id]) s.scheduled_checks[id]={};
const c=s.scheduled_checks[id];
// Set fields according to outcome — only set fields that should change
// outcome=unavailable: c.last_unavailable_at='<ISO>'; (leave last_run unchanged)
// outcome=error: c.last_error_at='<ISO>'; (leave last_run unchanged)
// outcome=empty: c.last_run='<ISO>'; c.consecutive_empty=<prior+1>;
// outcome=actionable|contextual: c.last_run='<ISO>'; c.consecutive_empty=0;
fs.writeFileSync(f, JSON.stringify(s,null,2)+'\n','utf-8');
} catch(e){ process.stderr.write('scheduled-checks state: '+e.message+'\n'); }
"
Substitute the actual id, ISO timestamp, and field assignments for the current outcome before running. Always exits cleanly — a failed write is logged to stderr only.
Append one line to .claude-code-hermit/sessions/SHELL.md under ## Progress Log:
[HH:MM] scheduled-checks — <id>: <outcome>; verdicts: accept=A downgrade=D suppress=S; outcome: <none|micro-queued|proposal-created|interval-proposal>
Use skipped for the id field and skipped for outcome when no check was due.
data-ai
Initializes or resumes a work session. Loads context from OPERATOR.md and SHELL.md, orients the agent, and establishes what to work on. Use at the beginning of every work session.
tools
Evolves hermit configuration and templates after a plugin update. Detects version gaps, presents new features, walks through new settings. Run after updating the plugin.
testing
Initializes the autonomous agent in the current project. Creates the state directory, templates, OPERATOR.md, and config.json. Appends session discipline to CLAUDE.md. Detects installed hermits. Run once per project, like git init.
tools
Generates Docker scaffolding and walks the operator through the full deployment — token setup, build, start, MCP plugin configuration, workspace trust, and verification. Offers to back up and overwrite existing Docker files. Run after /hatch.