SUPERSEDED · 2026-05-29 The headline numbers below ("median trust 0.25 → 0.53 across 5 skills") were measured against a self-built metric the user couldn't see. A controlled three-arm experiment (BW-2026-006) falsified the central claim under blind judging. v0.5 of skills2 lost to a prompt-engineered checklist by 1 median point on framework fidelity. v0.6 fixed half the gap. v0.7 closes it. The corrected case-file is the canonical one. This issue stays live for the historical record.

Build artifact · runtime extension · installable

Skills 2.0 — making Anthropic's prose skills a Python contract

Issue BW-2026-005
Type 04 · build artifact
Published 2026-05-28
Artifact skills2 runtime
Data 48 rows · 5 skills · 24 cases

TL;DR

0.25 to 1.00. Median trust score for growth-accounting under Anthropic's SKILL.md v1 vs. the same skill compiled through skills2 transform and run on the Skills 2.0 runtime — Python @step decorators, Pydantic I/O schemas, append-only telemetry, post-hook audit.

A 4x lift on one fully-implemented skill is the ceiling. The floor — what you get on a v1 skill that has been transformed but never hand-tuned, where every step function is still a stub returning {} — is also better than v1: 0.25 to 0.53 across four other skills, all measured against transformer-generated eval cases.

skills2 is the case for adding a Python contract under Anthropic's prose contract, without removing the prose.

What a prose contract leaks.

Anthropic shipped Agent Skills in late 2025 as a SKILL.md file with YAML frontmatter and progressive disclosure: three levels of loading, scripts and references and templates as siblings, a description string Claude matches against the user's prompt. The spec is excellent for distribution. Forty skills cost about 1,500 tokens of overhead.

The spec is also a prose contract. There is no I/O schema. There is no proof a step ran. There is no telemetry. There is no evaluation gate. The skill describes its decision flow in the body and trusts Claude to follow it. When Claude does not, no one finds out until the output is wrong.

Seven specific symptoms, each one you have probably seen, none caught by output-passing evals:

Weakness in v1What goes wrong
No I/O schema"Produce a JSON object with these fields" — sometimes the field is missing.
No execution proofStep N skipped silently when the model decided it could infer the answer.
No telemetryA skill drifts over six months. The next maintainer rediscovers from scratch.
String compositionSkill A passes a result to Skill B by writing it into prose. Skill B parses prose.
Activation by descriptionThe skill fires on adjacent intents, or fails to fire on the intended one.
No evalTwo engineers ship two versions of the same skill; only one runs the framework correctly.
Static versioningA prompt edit goes live without re-checking the pipeline still works.

You can ignore each one for a while. The cost compounds. By skill 20, you have 40 prose contracts the model honors with one degree of freedom each.


The five layers.

Skills 2.0 preserves the v1 prose verbatim. SKILL.md is unchanged, still loaded by Claude exactly as before. Five Python layers sit next to it.

1. Manifest — skill.toml

Every step gets a machine-readable contract.

[[steps]]
id = "compute_single_period_identity"
order = 4
required = true
fn = "runtime.steps:compute_single_period_identity"
invariants = ["runtime.validators:identity_closes"]

2. Runtime — the @step decorator

Each step is a Python function the runtime wraps with order checking, Pydantic I/O validation, invariant enforcement, and append-only telemetry to ~/.claude/skills2/runs/.

@step(
    order=4,
    requires=["pick_decomposition_form"],
    invariants=["runtime.validators:identity_closes"],
    output_schema=IdentityCheck,
)
def compute_single_period_identity(prev_mau, new, resurrected, churned, current_mau):
    implied = prev_mau + new + resurrected - churned
    residual = current_mau - implied
    return IdentityCheck(..., identity_closes=abs(residual) <= 1.0)

The invariant — prev_mau + new + resurrected − churned = current_mau — closes or it does not. There is no "the model thinks it does."

3. MCP server — every step a tool

Each @step function auto-registers as an MCP tool named mcp__skills2__{skill}__{step_id}. Claude calls them natively. Pydantic-model arguments bridge transparently to JSON Schema at the tool boundary, so FastMCP can introspect the surface without seeing the skill's internal types.

For growth-accounting, this exposes fifteen tools — ten step functions plus __start_run, __end_run, __audit_run, and two global listing tools.

4. Hooks — pre-injection, post-audit

A single dispatcher reads stdin JSON from Claude Code and routes:

Installation into ~/.claude/settings.json is idempotent. Existing hooks are identified by a substring marker and preserved.

5. Audit — three-axis trust score

Three dimensions, weighted:

AxisWeightWhat it measures
FIDELITY0.35Final output matches the Pydantic schema; every invariant passed.
COVERAGE0.40Required steps fired in order.
ANCHORING0.25Response text contains the skill's canonical vocabulary.

Threshold default 0.80. Below threshold the post-hook surfaces missing-step and failed-invariant lists in the transcript. The next turn sees the audit; the model corrects. No hard blocking — Claude Code's hook protocol does not currently support "reject and rewrite," and inventing it would couple Skills 2.0 to a contract that might change.

6. Evals — cases.jsonl

Each case has must_call, must_mention, must_not, and (for tests of failure modes) expected_audit: fail. The eval runner returns a pass-rate. CI gates version bumps on regression.


Five skills, 48 rows, one number.

Five skills, transformed once, run under two versions:

Skill Cases Median v1 Median v2 Δ
growth-accounting (fully implemented)60.251.00+0.75
psych-framework50.250.53+0.28
retention-analyze30.250.53+0.28
abw-design40.250.53+0.28
analytical-argument-audit60.250.53+0.28
Overall median240.250.53+0.28 (2.1x)

Three readings.

The v1 baseline at 0.25 is the ANCHORING component alone. The prose teaches the model the vocabulary, the model uses it, nothing else can be scored because nothing else fires. That is the ceiling on Skills-as-prompts. Not low because the model is dumb; low because there is nothing else to measure.

The 0.53 v2 number across four skills is what skills2 transform produces with zero manual code. The stubs return {}. The schema validates trivially. The invariants are empty. Coverage rises from 0 to 0.7 because the steps fire in order. Anchoring holds. This is the floor of Skills 2.0 — the per-skill effort is running one CLI command.

The 1.00 on growth-accounting is what the runtime can reach when the step bodies actually compute the quantities the prose names. The MAU identity closes or the invariant raises. The quick-ratio classifier output matches the threshold cuts or the consistency check fails. The dominant-flow function gets called or COVERAGE drops below threshold and the hook tells the model on the next turn.

The line from 0.53 to 1.00 is per-skill work. Skills 2.0 does not collapse it. It makes the work measurable.

What this issue does not claim

(1) That five skills generalize to the full corpus of 52 — the headline number is the median across the chosen sample, not extrapolated. (2) That generic eval cases — three per skill, generated by the model from the "When to use" section — substitute for hand-tuned cases. (3) That Skills 2.0 makes a bad skill good: if the SKILL.md prose is wrong about the framework, the contract enforces the wrong thing more reliably. (4) That Skills 2.0 eliminates the model — the orchestration is still Claude. The contract bounds the failure modes the model can produce. It does not bound whether the model is the right tool for the work. (5) That the MCP and hooks layers will continue to work unchanged through 2026 — they depend on Claude Code's hook protocol staying stable. Fail-open is the right default.

Artifacts

Sources

  1. Anthropic (2025). Equipping agents with Agent Skills. anthropic.com/engineering. The v1 spec this work extends.
  2. Anthropic (2026). Agent Skills API documentation. platform.claude.com. Progressive disclosure model.
  3. Sanchez de la Sierra, A. (2026). cto-strategy vault-contract pattern. Internal repository. Three-tier enforcement (soft injection, pre-hook reminder, post-hook BLOCKED loop). The Skills 2.0 trust-score architecture is the generalized form.
  4. Colvin, S. (2024). Pydantic AI. github.com/pydantic/pydantic-ai. Single-call LLM I/O validation pattern Skills 2.0 generalizes to multi-step procedures.
  5. Willard, B., Louf, R. (2023). Outlines: typed structured outputs. github.com/outlines-dev/outlines.
  6. Lowin, J. (2024). FastMCP. github.com/jlowin/fastmcp. The MCP library Skills 2.0 uses; same library that powers the ra-pm internal server.
  7. Raising Agents (2026). Skills 2.0 baseline dataset. evals/corpus_baseline/results.csv, 48 rows across 5 skills × 2 versions, 2026-05-28. GitHub.

Back to Behavior Watch