agent-skills-platform

Agent-run reliability evidence with Caliper

Status: pilot. Two bundled example skills carry a Caliper spec; the factory emits one for every new skill, and team_marketplace.py reliability runs it per platform. Agent runs happen on the operator’s machine; CI only checks that the specs parse.

What it adds

Every skill this factory produces ships file-level evals (scripts/run_evals.py): the skill’s own pipeline runs against golden cases and shell checks. Those evals never start an agent. They cannot tell you whether an agent that has the skill installed will notice it, follow its instructions instead of improvising, or produce the same result three times in a row.

Caliper (caliper-eval, MIT) answers those questions. It installs the skill into the agent’s normal skills folder inside a fresh temporary HOME, runs each task k times, grades every attempt with a Python assert: and an LLM-judged expect:, records which skills the agent loaded, and saves one JSON file per run with SHA-256 hashes of the skill files it tested.

Question File-level evals Caliper
Does the pipeline script produce the right file? yes yes (via assert:)
Does an agent discover the skill from its description? no yes (activates:)
Does the agent follow the skill instead of improvising? no yes (expect: + tool transcript)
Is the result consistent across repeated runs? no yes (pass^k)
Does the skill beat the bare agent? no yes (--ablate)
Does it run on more than one agent runtime? no yes (--model claude-code / codex)

The pilot already produced one finding the file-level evals cannot: on stock-analyzer, Claude Code read the skill, judged its mock pipeline unhelpful, computed indicators itself against a live market source, and skipped the requested output file. That is an instruction-following failure of the SKILL.md, invisible to run_evals.py.

Install and run

uv tool install caliper-eval==0.11.0      # or: pipx install caliper-eval==0.11.0
caliper --help

Backends are CLI agents only: claude-code, codex, pi, hermes. There is no direct API backend and no GitHub Copilot backend. The backend and judge are runtime flags, never spec fields.

SPEC=references/examples/stock-analyzer/evals/caliper/stock-analyzer.eval.yaml
caliper validate "$SPEC"

# Iterate at k=1 until the spec itself is stable.
caliper run "$SPEC" --k 1 --timeout 180 --model claude-code --judge-model codex --verbose

# Measure. --workers 1 is required: attempts of one task run in parallel otherwise and
# the fixed /tmp work paths in the spec would collide.
caliper run "$SPEC" --k 3 --workers 1 --timeout 180 --model claude-code --judge-model codex \
  --output .caliper/runs/stock-analyzer-claude-code.json
caliper run "$SPEC" --k 3 --workers 1 --timeout 180 --model codex --judge-model claude-code \
  --output .caliper/runs/stock-analyzer-codex.json

# The real baseline: same tasks, skill removed.
caliper run "$SPEC" --k 3 --workers 1 --timeout 180 --model claude-code --judge-model codex \
  --ablate stock-analyzer --output .caliper/runs/stock-analyzer-claude-code-ablated.json
caliper compare .caliper/runs/stock-analyzer-claude-code.json \
                .caliper/runs/stock-analyzer-claude-code-ablated.json

Raw runs land in a .caliper/ directory (gitignored). Pruned copies without transcripts are committed under docs/verification/caliper/<skill>/ as evidence.

Spec layout

A spec lives at <skill>/evals/caliper/<skill>.eval.yaml. It is part of the skill’s behavior-defining files, so adding or editing one changes the verification fingerprint and VERIFICATION.md must be regenerated (python3 scripts/generate_verification.py <skill>).

skills:
  - ../../SKILL.md                 # the whole skill directory is installed under its frontmatter name
sandbox:
  forbidden_files:
    - "evals/"                     # golden cases are answer keys: not installed, not readable
    - "references/examples/"       # the repository checkout is a back door around the install
tasks:
  - name: Happy path
    setup: rm -rf /tmp/caliper-x && mkdir -p /tmp/caliper-x
    cleanup: rm -rf /tmp/caliper-x
    prompt: "…a request a real user would type, with absolute output paths…"
    activates: [skill-name]        # exact set of skills expected to load
    expect: "…what the judge must see in the transcript and final reply…"
    assert: |                      # deterministic; runs from the spec directory, 30 s cap
      from pathlib import Path
      assert Path("/tmp/caliper-x/out.json").exists()
  - name: Stays silent on an unrelated request
    prompt: "Write a haiku about autumn rain."
    activates: []                  # silence probe: no judge call, cheap

Three tasks per skill are enough for the pilot: a happy path, an edge case, and a silence probe. Put every mechanically checkable claim in assert:; keep expect: for what only a transcript reveals (did it run the skill’s script, did it refuse to invent values).

Operator flow: one command per skill

The marketplace operator’s agent does not type the commands below by hand. It runs:

python3 scripts/team_marketplace.py reliability <skill> --department <dept> --marketplace <dir>

which, for every declared platform Caliper can drive and whose CLI is installed, runs the spec, binds the run, and certifies what passes (see the team marketplace guide). check --release --require-reliability then refuses a release whose claude-code or codex certification carries no caliper:* checks. The creator agent’s only duty is to emit evals/caliper/<skill>.eval.yaml in Phase 5 from references/templates/caliper-eval-template.yaml.

The rest of this page is the manual path, useful for iterating on a spec.

From a run to marketplace certification

scripts/caliper_evidence.py turns a run into the evidence JSON that team_marketplace.py certify --evidence already accepts:

python3 scripts/caliper_evidence.py .caliper/runs/stock-analyzer-claude-code.json \
  --skill references/examples/stock-analyzer \
  --output docs/verification/caliper/stock-analyzer/claude-code-2026-09-15.json \
  --evidence-out /tmp/stock-analyzer-claude-code-evidence.json
python3 scripts/team_marketplace.py certify stock-analyzer --department finance \
  --platform claude-code --evidence /tmp/stock-analyzer-claude-code-evidence.json \
  --marketplace ./acme-skills

The adapter refuses, with exit code 1, when:

Certification records store only check names, so every name carries its threshold and the observed value, for example caliper:success_rate>=0.90(observed=1.00), caliper:unusable_attempts<=1(observed=0), caliper:model=cli-default, caliper:skill_sha256=5b56aebdaaf2. Certification is version-bound and cleared on update, exactly like any other platform evidence.

Read the numbers correctly

Limits