一键导入
skill-evals
Validate skill outputs against assertions, diff vs prior eval to flag regressions, file issues for new failures, and queue concrete fixes
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Validate skill outputs against assertions, diff vs prior eval to flag regressions, file issues for new failures, and queue concrete fixes
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Audit every enabled skill's upstream file dependencies for staleness — flags chained skills about to consume yesterday's article or a long-dead topic file
Audit .github/workflows and composite actions with zizmor + actionlint, classify findings against the prior audit, auto-fix Critical/High regressions, and open a PR only when something actually changed.
Weekly API cost report — computes dollar costs from token usage, flags anomalies, forecasts burn, and prescribes concrete optimizations
Weekly partial-correlation of compute economics against a Hyperliquid macro basket — DePIN-token proxy track runs every week (n>180d), sweep-P&L track defers until n≥30 joined days
Score frontier LLMs (Claude, GPT, Gemini, DeepSeek, Grok) on a private compute-markets task corpus, track score deltas across releases, flag public-vs-private divergence
Save a note as one or more atomic notes under memory/notes/ (and optionally Supernotes). Splits bundled inputs into separate atomic files.
| name | Skill Evals |
| description | Validate skill outputs against assertions, diff vs prior eval to flag regressions, file issues for new failures, and queue concrete fixes |
| var | |
| tags | ["meta"] |
${var} — Skill name to evaluate. If empty, evaluates all skills in
evals.json.
Today is ${today}. Read memory/MEMORY.md for context.
This skill exists to catch quality regressions between runs — not just to re-state a snapshot of the latest output. The lede is what changed since last eval and what to do about it, not a flat pass/fail table.
skills/skill-evals/evals.json — assertion manifest (read with jq; if parse fails, retry once after 5s, then exit SKILL_EVALS_ERROR).aeon.yml — registered skills, enabled flags, cron schedules.memory/cron-state.json — total_runs, success_rate, last_quality_score, last_failed, last_success per skill.memory/issues/INDEX.md — currently open issues (used to dedupe issue filing in step 5b).articles/skill-evals-*.md (sorted descending, excluding today's). If none exist, mark prior_run as BOOTSTRAP — every result is NEW_*.If evals.json is missing or has zero skills keys, run ./scripts/eval-audit --stubs to scaffold a starter spec and exit SKILL_EVALS_BOOTSTRAP with a notify telling the operator to commit the stub.
Call ./scripts/eval-audit --json and parse:
summary.coverage_pct, summary.covered, summary.uncovered_enabled, summary.uncovered_disableduncovered_enabled[].skill and .inferred_pattern — these are the spec-gap candidates surfaced in the Action Queue.Do not re-implement coverage detection in prose. If the script fails, fall back to the in-memory check (compare evals.json keys to aeon.yml enabled skills) and mark eval-audit=fail in the source-status footer.
${var} is set → evaluate only that one skill (skip if not in evals.json and notify "skill-evals: ${var} has no spec — add an entry to evals.json").evals.json.a. Find latest output: glob output_pattern, sort descending by filename. If empty → status NO_OUTPUT, root_cause no_file_match, skip remaining checks.
b. Empty/stale: if file size is 0 bytes → FAIL, root_cause empty_file. If file mtime is older than 2× expected_cadence (derived from the skill's cron in aeon.yml; fall back to 14 days if cron is workflow_dispatch or unparseable) → STALE, root_cause stale_file. Stale outputs still run their assertions but are reported as STALE so dashboard noise is correct.
c. Word count: count words; fail if < min_words → root_cause word_count (record actual vs threshold).
d. Required patterns: for each pattern (pipe-separated alternatives), grep with -E. Missing → root_cause missing_pattern:<pattern>.
e. Forbidden patterns: any match → root_cause forbidden_pattern:<pattern>.
f. Numeric checks: for each entry, extract first regex match. Outside [min, max] → root_cause numeric_oob:<label>. If no match found and entry has skip_if_not_found: true, skip; otherwise WARN with root_cause numeric_missing:<label>.
g. Quality cross-check: read memory/skill-health/{skill}.json. If avg_score < 2.5 → status QUALITY_DEGRADED, root_cause quality_score:<avg>. If 2.5 ≤ avg_score < 3.5, record as note (no status change). If file missing, record quality=unknown.
Final status precedence: NO_OUTPUT > FAIL > STALE > QUALITY_DEGRADED > WARN > PASS.
Parse the prior eval article's results table. For each skill produce one of:
NEW_FAIL — was PASS/STALE/WARN, now FAIL/QUALITY_DEGRADED/NO_OUTPUT
FIXED — was failing, now PASS
STILL_FAIL — was failing, still failing (carry the issue ID forward)
NEW_PASS — wasn't in prior (newly added to evals.json)
NEW_NO_COVERAGE — covered prior, no eval entry now (rare; usually means evals.json edit)
STABLE — same status both runs
a. Issue filing. For every NEW_FAIL and NEW_QUALITY_DEGRADED:
memory/issues/INDEX.md — if an open issue already names this skill in the title, skip (avoid duplicates).memory/issues/ISS-{NNN}.md with frontmatter:
---
id: ISS-{NNN}
title: {skill}: {root_cause_short}
status: open
severity: {high if NEW_FAIL, medium if QUALITY_DEGRADED}
category: {map root_cause: missing_pattern→prompt-bug, forbidden_pattern→prompt-bug, numeric_oob→quality-regression, word_count→quality-regression, stale_file→missing-secret-or-cron, empty_file→quality-regression, quality_score→quality-regression, no_file_match→missing-secret-or-cron}
detected_by: skill-evals
detected_at: {ISO timestamp}
affected_skills: [{skill}]
root_cause: {full root_cause string}
---
{one-paragraph context with file path, expected vs actual, link to article}
{NNN} = next free 3-digit ID (scan memory/issues/ISS-*.md, take max + 1, zero-pad).memory/issues/INDEX.md Open table.b. Issue closing. For every FIXED: scan memory/issues/ISS-*.md for an open issue whose affected_skills contains this skill and detected_by: skill-evals; flip status: resolved, set resolved_at, move row from Open → Resolved table in INDEX.md. (Don't touch issues filed by other detectors.)
One-line verdict, picked by precedence:
SKILL_EVALS_REGRESSED — any NEW_FAIL existsSKILL_EVALS_QUALITY_DROP — any NEW_QUALITY_DEGRADED (no NEW_FAIL)SKILL_EVALS_RECOVERED — FIXED ≥ 1 and zero new failuresSKILL_EVALS_COVERAGE_CLIFF — coverage_pct dropped ≥ 10 points vs last run, or absolute coverage_pct < 25 and last run was ≥ 25SKILL_EVALS_OK — all stable, all greenA short, ordered, concrete checklist at the top of the article. Cap at 8 items. Each item is one line, naming a specific skill and a specific next step:
Patch evals.json:{skill} — {root_cause}Investigate {skill} — {root_cause} (ISS-{NNN})Dispatch {skill} — no output in {N} daysAdd evals.json entry for {skill} — pattern: {inferred_pattern} (one line per uncovered enabled skill, max 5; if more, summarize "+N more — see Coverage Gaps")If the queue is empty, write Action Queue: none — all green.
Path: articles/skill-evals-${today}.md. Skeleton:
# Skill Evals — ${today}
**Verdict:** {VERDICT}
**Coverage:** {covered}/{enabled_total} ({coverage_pct}%) {↑↓ vs prior or "(first run)"}
**Diff:** {N_NEW_FAIL} new fail · {N_FIXED} fixed · {N_STILL_FAIL} still failing · {N_STABLE} stable
## Action Queue
1. ...
2. ...
## Regressions (NEW_FAIL + NEW_QUALITY_DEGRADED)
| Skill | Status | Root cause | Issue |
|-------|--------|------------|-------|
| ... | NEW_FAIL | missing_pattern:stars | ISS-014 |
## Recovered (FIXED)
| Skill | Was | Now |
|-------|-----|-----|
## Still Failing
| Skill | Status | Root cause | Issue | Failing since |
|-------|--------|------------|-------|---------------|
## Full Results
| Skill | Status | Diff | Root cause | Quality | Words | Last output |
|-------|--------|------|------------|---------|-------|-------------|
## Coverage Gaps (enabled in aeon.yml, missing from evals.json)
- {skill} — inferred pattern: `{inferred_pattern}`
## Sources
- evals.json={ok|fail} · cron-state={ok|fail} · skill-health={ok|empty|fail} · eval-audit={ok|fail} · prior-article={ok|none}
Omit empty sections (no Recovered section if zero FIXED, etc.). Keep the Coverage Gaps section bounded to 10 lines max — overflow into a +N more summary.
Only call ./notify when one of the following holds:
SKILL_EVALS_REGRESSED, SKILL_EVALS_QUALITY_DROP, or SKILL_EVALS_COVERAGE_CLIFFSKILL_EVALS_RECOVERED (good news worth a ping)Stay silent on SKILL_EVALS_OK (still write the article + log entry; just don't ping). This trains the operator that a notification means action is needed.
Notify body (concise, soul-voice):
*Skill Evals — {VERDICT}*
{N_NEW_FAIL} new fail · {N_FIXED} fixed · coverage {coverage_pct}%
Top action: {action_queue[0]}
Article: articles/skill-evals-${today}.md
If N_NEW_FAIL > 0, append the first 3 regressions as {skill}: {root_cause} lines.
Append to memory/logs/${today}.md:
### skill-evals
- Verdict: {VERDICT}
- Diff: {N_NEW_FAIL} new fail / {N_FIXED} fixed / {N_STILL_FAIL} still failing / {N_STABLE} stable
- Coverage: {covered}/{enabled_total} ({coverage_pct}%)
- Issues filed: [list ISS-IDs]
- Issues closed: [list ISS-IDs]
- Action queue head: {action_queue[0] or "none"}
All inputs are local files (evals.json, aeon.yml, memory/*, articles/*, scripts/eval-audit). No outbound HTTP — no fallback needed. ./scripts/eval-audit is a local bash script and uses jq; if jq is missing (rare on GH Actions ubuntu runners), the script will exit non-zero — mark eval-audit=fail in the source-status footer and continue with the in-memory coverage check.
ISS-{NNN} number.detected_by: skill-evals issues are closeable here).SKILL_EVALS_OK — silence is the correct signal on a green week.output_pattern, min_words, required_patterns, forbidden_patterns, numeric_checks) — additions allowed (skip_if_not_found, expected_cadence), removals are breaking.