Files
gbrain/skills/skillify/SKILL.md
T
a1a2671c21 v0.28.4 feat(skillpack): enhance skillify with cross-modal eval quality gate (#674)
* feat(skillpack): enhance skillify with cross-modal eval quality gate

Updates skillify from v1.0.0 to v2.0.0 with the key innovation:
cross-modal evaluation runs BEFORE tests (step 3) to establish
quality, then tests lock in the proven-good behavior.

Key changes:
- 11-item checklist (was 10) - adds cross-modal eval as step 3
- Cross-modal eval uses 3 models to score output on 5 dimensions
- Quality gate: all dimensions ≥ 7 average before proceeding to tests
- Prevents locking in mediocrity through tests-first approach
- References cross-modal-review skill for eval pipeline
- Updated all gbrain-specific paths (bun test, scripts/*.ts)
- Maintains compatibility with gbrain check-resolvable workflow

The meta-skill for turning raw features into properly-skilled,
tested, resolvable capabilities. Cross-modal eval ensures output
quality before tests cement the behavior.

* feat: skillify hardened via 2 cross-modal eval cycles (8.1/10)

Applied top improvements from GPT-5.5 + Opus 4-7 + DeepSeek V4 Pro:
- Named 3 frontier models explicitly with provider table
- Inlined eval prompt template with CONTEXT param + scoring calibration
- Defined aggregation math: mean >= 7 AND no single dim < 5
- Added eval receipt JSON schema
- Structured 3-cycle fix loop with before/after delta tracking
- Added worked example (summarize-pr, end-to-end)
- Added cost guardrails (skip < 200 tokens, max 9 API calls)
- Added representative input selection rule
- Added SKILL.md frontmatter template (copy-paste ready)
- Added Phase 0 decision gate (is this worth skillifying?)

Also includes cross-modal-eval runner recipe with robust JSON
parsing for LLMs that return malformed JSON (3-tier repair).

* chore(recipes): remove cross-modal-eval.mjs

Superseded by `gbrain eval cross-modal` (next commit). The .mjs script
was the original PR's hand-rolled provider stack; the replacement reuses
src/core/ai/gateway.ts so config/auth/model-aliasing comes from the
canonical recipe registry instead of a parallel stack.

No code references the .mjs (it was invoked by skill prose only), so
this delete is independently safe to bisect through.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(eval): cross-modal-eval core module + unit tests

Pure-logic foundation for the new `gbrain eval cross-modal` command
(wired in the next commit). All five modules are self-contained — no
CLI surface, no I/O outside the receipt writer's mkdirSync. Imported
from src/core/ai/gateway.ts at runtime via gwChat (no config impact
at load time).

Modules:
  - json-repair.ts:    parseModelJSON 4-strategy fallback chain.
                       Adversarial nuclear-option throws rather than
                       fabricating scores (Q6 + Q3 in plan).
  - aggregate.ts:      verdict logic. PASS = (>=2 successes) AND
                       (every dim mean >= 7) AND (every dim min
                       across models >= 5). INCONCLUSIVE when <2/3
                       models returned parseable scores — closes the
                       v1 .mjs `Object.values({}).every(...) === true`
                       empty-array silent-PASS bug (Q2 + Q3).
  - receipt-name.ts:   receipt filename binds (slug, sha8 of SKILL.md)
                       so `gbrain skillify check` can detect stale
                       audits (T10 in plan).
  - receipt-write.ts:  thin wrapper over writeFileSync that auto-mkdirs
                       the parent directory. Standalone module because
                       gbrainPath() does NOT auto-mkdir (T5 plan
                       correction — Codex caught this).
  - runner.ts:         orchestrator. Promise.allSettled across 3 slots
                       per cycle; up to 3 cycles; stops early on PASS
                       or INCONCLUSIVE. Default slots: openai:gpt-4o /
                       anthropic:claude-opus-4-7 / google:gemini-1.5-pro.
                       estimateCost() exports a small per-model
                       pricing table (drifts; refresh alongside
                       model-family bumps).

Tests (32 cases total, all green):
  - json-repair.test.ts:  10 cases (clean JSON, fences, trailing
                          commas, single quotes, embedded newlines,
                          mismatched braces, nuclear-option success
                          + adversarial throws, empty input,
                          numeric-shorthand scores).
  - aggregate.test.ts:    8 cases pinning Q2/Q3/dedup. The 0-of-3
                          INCONCLUSIVE case is the regression guard
                          for the v1 silent-PASS bug.
  - cli.test.ts:          12 cases on receipt-name / receipt-write /
                          GBRAIN_HOME isolation. Uses withEnv()
                          helper for env mutation (R1 isolation rule).

Verifies bisect-clean: typecheck passes, all 32 unit cases green.
The runner.ts import of gateway.chat() is dead until commit 3 wires
the CLI surface.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(eval): wire `gbrain eval cross-modal` CLI subcommand

User-facing surface for the multi-model quality gate. Three different-
provider frontier models score the OUTPUT against the TASK on a 5-dim
rubric. Verdict drives exit code: 0 PASS, 1 FAIL, 2 INCONCLUSIVE
(<2/3 models returned parseable scores per Q3 in plan).

Wiring touches three files:

  - src/commands/eval-cross-modal.ts (new, ~290 lines)
    CLI handler. Self-configures the AI gateway from loadConfig() +
    process.env so it works without `gbrain init` (the cli.ts no-DB
    branch bypasses connectEngine()). Defaults: cycles=3 in TTY,
    cycles=1 in non-TTY (T11 partial cost guardrail — limits scripted
    bulk spend; full --budget-usd hard cap is a v0.27.x TODO). Prints
    estimated max-cost-per-cycle to stderr before each run. Uses
    gbrainPath('eval-receipts') for receipt directory.

  - src/cli.ts (no-DB dispatch branch, 5-line addition)
    Special-cases `eval cross-modal` BEFORE the existing
    handleCliOnly path that requires connectEngine(). Mirrors the
    `dream` no-DB pattern but doesn't even attempt the connect — the
    command never touches the DB. New users can run the gate before
    `gbrain init` (T3 in plan).

  - src/commands/eval.ts (sub-subcommand dispatch)
    Adds `cross-modal` alongside `export`/`prune`/`replay`. The
    cli.ts branch takes precedence in the user-facing path; this
    branch only fires when callers re-enter runEvalCommand with an
    existing engine. Engine is intentionally unused — the handler
    self-routes.

  - test/e2e/cross-modal-eval.test.ts (new, 4 cases)
    Mocked-fetch E2E. Lives at test/e2e/* (NOT *.serial.test.ts) per
    plan T8: test/e2e/* is exempt from the test-isolation lint and
    already runs serially via scripts/run-e2e.sh, so the
    mock.module() call doesn't need a quarantine rename. Cases:
    PASS / FAIL (mean<7) / FAIL (min<5 — Q2 floor) / INCONCLUSIVE
    (2 mock 5xx — Q3 contract).

The runner from commit 2 now has live callers. typecheck passes;
the 4 E2E cases all green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(skillify): add informational 11th item (cross-modal eval)

Promotes the skillify contract from 10 to 11 items. The 11th item
(cross-modal eval) is `required:false` per T7 in the plan — a
missing or stale receipt surfaces in the audit output but does not
fail the gate. Existing skills keep their current required-score;
the bump is additive, not breaking.

Changes:

  - src/commands/skillify.ts
    Header jsdoc updated 10-item -> 11-item. No code-flow changes.

  - src/commands/skillify-check.ts (the per-skill audit; not
    src/commands/skillpack-check.ts which is a different command —
    plan T6 corrected the conflation in the original plan)
    New informational item at position 11. Reuses
    findReceiptForSkill() helper from
    src/core/cross-modal-eval/receipt-name.ts to detect:
      * found  — receipt matches current SKILL.md sha-8
      * stale  — receipt exists for an older SKILL.md
      * missing — no receipt yet
    Audit output cases pass through to existing pretty/JSON formats.

  - src/core/skillify/templates.ts
    Scaffolded SKILL.md now includes a "Phase 3: Cross-modal eval
    (informational)" section with copy-paste `gbrain eval cross-modal`
    invocation, pass criteria, and receipt-naming convention. Helps
    new skill authors discover the gate.

  - test/skillify-scaffold.test.ts
    New T9 case verifies the scaffold emits the Phase 3 section,
    points at the correct command, documents the receipt path, and
    appends exactly one resolver row. Replaces the original plan's
    `gbrain skillify scaffold demo-eleven` shell verification (which
    Codex caught as invalid + repo-mutating).

Verifies: typecheck passes; scaffold test 19/19 (was 18, +1 T9 case).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: skillify v1.1.0 + cross-modal-eval references

Documentation catches up with the new behavior shipped in commits 1-4.

  - skills/skillify/SKILL.md (1.0.0 -> 1.1.0)
    Full rewrite. Frontmatter version is additive (T7 in plan); the
    11th item is informational, not breaking. Phase 3 now points at
    `gbrain eval cross-modal` with copy-paste invocation, default
    slot table, pass criteria, receipt-naming convention, cycles +
    cost guardrails (T11 partial cap), provider configuration via
    the AI gateway, and the cycle-1/2/3 fix loop. Adds Output Format
    section (skills-conformance.test.ts requires it). Drops the
    original `(or lib/cross-modal-eval.ts)` parenthetical (Q5 plan
    correction — that path never existed).

  - skills/cross-modal-review/SKILL.md
    Adds 4-line Relationship section pointing at `gbrain eval
    cross-modal` (D3 plan reciprocal). Distinguishes the manual
    second-opinion gate (this skill) from the automated multi-model
    score-and-iterate gate (the new command).

  - CLAUDE.md
    Key Files entries for src/commands/eval-cross-modal.ts and the
    five new src/core/cross-modal-eval/* modules. Commands list
    gains the `gbrain eval cross-modal` entry under v0.27.x. Notes
    the non-TTY default 1-cycle behavior + the gbrainPath('eval-
    receipts') resolution.

  - TODOS.md
    Four v0.27.x follow-ups filed under a new "cross-modal-eval"
    section: full --budget-usd cap (T11 follow-up), subagent
    integration (recovers cross-process rate-leases T4 deferred),
    skill adoption telemetry (revisit T7=C with data after 30 days),
    docs/cross-modal-eval.md user guide.

  - llms-full.txt
    Regenerated via `bun run build:llms` to match the CLAUDE.md
    edits — sync guard at test/build-llms.test.ts requires this.

Verifies: typecheck passes; skills-conformance 199/199 green;
build-llms 7/7 green; full unit fast loop 3861/3861 green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: bump version and changelog (v0.28.4)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: garrytan-agents <garrytan-agents@users.noreply.github.com>
Co-authored-by: Garry Tan <garrytan@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:39:56 -07:00

11 KiB
Raw Blame History

name, version, description, triggers, tools, mutating
name version description triggers tools mutating
skillify 1.1.0 The meta skill. Turn any raw feature into a properly-skilled, tested, resolvable unit of agent capability. Cross-modal eval is the recommended Phase 3 quality gate: 3 frontier models from different providers critique the output, you iterate to quality, THEN write tests that lock in the proven-good behavior.
skillify this
skillify
is this a skill?
make this proper
add tests and evals for this
check skill completeness
exec
read
write
true

Skillify — The Meta Skill

Relationship to /cross-modal-review: That skill is the manual mid-flow "second opinion" gate (one model reviews work product before commit). This skill's Phase 3 below uses gbrain eval cross-modal instead — three different-provider frontier models score-and-iterate on a documented dimension list before tests cement behavior. Use /cross-modal-review for ad-hoc second opinions; use Phase 3 here when skillifying a feature.

Contract

A feature is "properly skilled" when all 11 checklist items pass. Item 3 (cross-modal eval) is informational in v1.1.0 — it does not gate the skillpack-check audit, but a missing or stale receipt is surfaced so the user knows where the gate stands.

The Checklist

□ 1.  SKILL.md           — skill file with frontmatter + contract + phases
□ 2.  Code               — deterministic script if applicable
□ 3.  Cross-modal eval   — 3 frontier models from 3 providers; informational
□ 4.  Unit tests         — cover every branch of deterministic logic
□ 5.  Integration tests  — exercise live endpoints
□ 6.  LLM evals          — quality/correctness cases for LLM-involving steps
□ 7.  Resolver trigger   — entry in skills/RESOLVER.md with real user trigger phrases
□ 8.  Resolver eval      — test that triggers route to this skill
□ 9.  Check-resolvable   — DRY + MECE audit, no orphans
□ 10. E2E test           — smoke test: trigger → side effect
□ 11. Brain filing       — if it writes pages, entry in brain/RESOLVER.md

Phase 0: Should This Be a Skill?

Before skillifying, check:

  • Will this be invoked 2+ times? (One-off work ≠ skill)
  • Is there >20 lines of logic? (Trivial helpers don't need full infrastructure)
  • Does it have a clear trigger phrase a user would actually say?

If no to all three, it's a script, not a skill. Move on.

Phase 1: Audit

Feature: [name]
Code: [path]
Missing items: [check each of the 11]

Phase 2: Write SKILL.md + Code (items 1-2)

SKILL.md frontmatter template (copy-paste):

---
name: my-skill
version: 1.0.0
description: |
  One paragraph. What it does, when to use it.
triggers:
  - "trigger phrase users actually say"
  - "another real trigger"
tools:
  - exec
  - read
  - write
mutating: false  # true if it writes to brain/disk
---

Body must include: Contract (what it guarantees), Phases (step-by-step), Output Format (what it produces).

Extract deterministic code into scripts/*.ts.

Phase 3: Cross-Modal Eval (item 3) — THE QUALITY GATE

Why this comes before tests

Tests lock in behavior. If the behavior is mediocre, tests lock in mediocrity. Cross-modal eval proves the quality bar FIRST, then tests cement it.

Step 1: Pick a representative input

Choose the input that exercises the skill's hardest documented use case. If unsure: use the primary trigger example from SKILL.md, or the most complex real-world input from the last 7 days of memory files.

Step 2: Run the skill, capture output

Run the skill on the representative input. The OUTPUT FILE is what gets evaluated.

Step 3: Run the eval gate

gbrain eval cross-modal \
  --task "What this skill is supposed to accomplish" \
  --output skills/<slug>/SKILL.md

The command runs 3 frontier models from 3 different providers in parallel, scores the OUTPUT against the TASK on 5 documented dimensions, and writes a receipt under ~/.gbrain/.gbrain/eval-receipts/<slug>-<sha8>.json (the sha-8 binds the receipt to the current SKILL.md content — re-running after edits writes a new receipt).

Default models (override per slot via --slot-a-model, --slot-b-model, --slot-c-model):

Slot Default Provider
A openai:gpt-4o OpenAI
B anthropic:claude-opus-4-7 Anthropic
C google:gemini-1.5-pro Google

These MUST be frontier models from DIFFERENT providers. Using a single provider's family or budget models defeats the purpose — different families have less correlated blind spots. Refresh the list when a new model generation ships.

Pass criteria (BOTH must be true):

  1. Every dimension's mean across successful models ≥ 7.
  2. No single model scored any dimension < 5 (the floor).

Inconclusive: fewer than 2 of 3 models returned parseable scores. Receipt is still written (forensics) but the gate is not authoritative. Exit code 2; CI wrappers should treat this as "did not run cleanly", not "failed quality gate".

Step 4: Cycle until you pass (≤3 cycles)

CYCLE 1:
  Eval → scores + top 10 improvements
  IF pass: → done, write tests
  ELSE:
    Apply top 10 improvements to the actual file
    Log: which improvements applied, what changed

CYCLE 2:
  Re-eval the FIXED output (same 3 models, same dimensions)
  Compare: before/after scores per dimension (track delta)
  IF pass: → done, write tests
  ELSE: apply remaining improvements + new ones

CYCLE 3 (final):
  Re-eval
  IF pass: → ship
  ELSE: → ship with KNOWN_GAPS section listing:
    - Which dimensions are still below 7
    - Which improvements couldn't be resolved
    - Why (e.g., "would require architectural change")

Cycles + cost guardrails

  • Default --cycles 3 in TTY, --cycles 1 in non-TTY (limits scripted bulk spend in CI loops).
  • The command prints an estimated max-cost-per-cycle from a small pricing constant before each run. Real cost varies with prompt size; treat the estimate as a ceiling for default --max-tokens 4000.
  • A --budget-usd N hard cap is a v0.27.x follow-up TODO.

Provider configuration

Models resolve through the gbrain AI gateway. Configure once with:

gbrain providers test    # see what's configured
gbrain config            # set keys

Or set env vars: OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, TOGETHER_API_KEY, etc. The gateway reads from ~/.gbrain/config.json plus process.env.

Cost expectations

3 cycles × 3 models = 9 frontier calls max per run. With Opus-class + GPT-4o-class + Gemini-1.5-Pro, expect $13 per full run on default --max-tokens 4000. Receipts include the per-call model identifiers so you can audit retroactively.

Skip cross-modal eval when:

  • Output is < 200 tokens (trivial — not worth 9 API calls).
  • The skill is a thin wrapper around a single API call (one cycle is enough).

Phase 4: Tests (items 4-6)

NOW that eval has proven quality, write tests that lock it in:

Unit tests — every branch of deterministic logic. Mock external calls. Integration tests — hit real endpoints. Catch bugs mocks hide. LLM evals — quality/correctness for LLM steps. Lighter than cross-modal eval — test specific behaviors.

Phase 5: Resolver + Check-Resolvable (items 7-9)

  1. Add to skills/RESOLVER.md with trigger phrases users ACTUALLY type
  2. Resolver eval: feed triggers, assert correct routing
  3. Check-resolvable:
    • Skill reachable from skills/RESOLVER.md (not orphaned)
    • No MECE overlap with other skills
    • No DRY violations (shared logic in lib/, not copy-pasted)
    • No ambiguous trigger routing

Phase 6: E2E + Brain Filing (items 10-11)

  • E2E smoke: full pipeline from trigger to side effect
  • Brain filing: add to brain/RESOLVER.md if the skill writes brain pages

Phase 7: Verify

bun test test/<skill>.test.ts                    # unit tests
gbrain skillify check skills/<slug>/scripts/<slug>.mjs --json | \
  jq '.[] | .items[] | select(.name | contains("Cross-modal"))'
ls ~/.gbrain/.gbrain/eval-receipts/              # receipt landed
gbrain check-resolvable --json | jq .ok          # resolver clean

Worked Example: Skillifying a "summarize-pr" Feature

Phase 0: Yes — invoked weekly, 50+ lines, clear trigger "summarize this PR"
Phase 1: Audit → SKILL.md missing, no tests, no resolver entry. Score: 1/11
Phase 2: Write SKILL.md + extract script to scripts/summarize-pr.ts
Phase 3: Cross-modal eval cycle 1 →
  GPT-4o: goal=6, depth=5, specificity=4 → "misses file-level diffs"
  Opus 4.7: goal=7, depth=6, specificity=5 → "no test plan in summary"
  Gemini 1.5 Pro: goal=6, depth=5, specificity=5 → "template feels generic"
  Aggregate: goal=6.3 FAIL, depth=5.3 FAIL
  Top improvements: add file-level changes, include test plan, use PR context
  → Apply fixes → Cycle 2: goal=8, depth=7.5, specificity=7 → PASS
Phase 4: Write 12 unit tests locking in the improved behavior
Phase 5: Add "summarize this PR" trigger to skills/RESOLVER.md
Phase 6: E2E test: feed a real PR URL → verify brain page created
Phase 7: All green. Score: 11/11

Quality Gates

NOT properly skilled until:

  • All required items pass (1-2, 4-10; 11 only when applicable).
  • Cross-modal eval (item 3) has a current receipt OR is explicitly waived with rationale (item 3 is informational; not blocking, but a missing receipt is visible in the audit).
  • All tests pass (unit + integration + LLM evals).
  • Resolver entry exists with real trigger phrases.
  • Check-resolvable shows no orphans, overlaps, or DRY violations.
  • Brain filing if applicable.

Output Format

Skillify produces three durable artifacts per skill:

  1. The skill tree on disk. skills/<slug>/SKILL.md, scripts/<slug>.mjs, routing-eval.jsonl, plus a test/<slug>.test.ts skeleton. Generated by gbrain skillify scaffold <name> and refined by the human/agent into a real implementation.
  2. A cross-modal eval receipt at ~/.gbrain/.gbrain/eval-receipts/<slug>-<sha8>.json. The sha-8 binds the receipt to the current SKILL.md content. gbrain skillify check surfaces the status (found / stale / missing) as informational.
  3. An audit verdict from gbrain skillify check: properly skilled | close — create: <missing items> | needs skillify — run /skillify on <target>. Score is <passed>/<total>. Required items gate the verdict; item 11 (cross-modal eval) is informational and never blocks PASS.

JSON output (gbrain skillify check --json) includes the same fields plus the per-item detail string, so agents can route on the structured envelope without parsing prose.

Anti-Patterns

  • Writing tests before cross-modal eval (locks in mediocrity)
  • Using budget models for eval (C student grading A student)
  • Using a single provider's family for all 3 slots (correlated blind spots)
  • Skipping eval "because the output looks fine" (your judgment isn't 3 models)
  • Eval without fix cycle (vanity metrics)
  • Code with no SKILL.md (invisible to resolver)
  • Tests that reimplement production code (masks real bugs)
  • Resolver entry with internal jargon (must mirror real user language)
  • Two skills doing the same thing (merge or kill one)
  • Running cross-modal eval on trivial outputs (< 200 tokens, not worth 9 API calls)