Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/modiqo/skillspec/llms.txt

Use this file to discover all available pages before exploring further.

A skill.spec.yml is a structured behavioral contract that lives next to your SKILL.md. It doesn’t replace prose — it structures the load-bearing decisions that prose alone can’t make inspectable. Where SKILL.md carries tone, context, and domain judgment, skill.spec.yml captures the parts that can be tested, checked, compiled, and traced: which route to take, what to forbid, which dependencies must exist, when to ask a clarifying question, and what a successful run must prove. The tagline is intentionally narrow: keep the prose, structure the decisions.

Anatomy of a contract

Every skill.spec.yml starts with a header block (schema, id, title, description) and then declares optional sections. Here is a representative contract based on the browser-research example:
schema: skillspec/v0
id: example.browser_research
title: browser research
description: Route browser inspection tasks to browser automation and keep URL discovery separate from page evidence.

# Candidate execution paths, ordered by rank (lower = earlier preference)
routes:
  - id: browser
    label: Browser automation
    rank: 10
  - id: native_search
    label: Native search for URL discovery
    rank: 20

# Conditional steering rules evaluated in file order
rules:
  - id: browser_tasks_use_browser
    when:
      user_says_any:
        - browse
        - open
        - click
        - snapshot
        - inspect
        - extract from page
    prefer: browser
    forbid:
      - native_search_as_answer
    allow:
      native_search: url_discovery_only
    elicit:
      - target_url
    reason: Page evidence must come from observing the page, not from search-result summaries.

# Bounded questions with typed choices
elicitations:
  target_url:
    question: Which URL should be inspected?
    choices:
      - id: user_provided_url
        label: Use the URL in the request
      - id: ask_for_url
        label: Ask for the URL
      - id: discover_url
        label: Search only to discover the URL
    default: ask_for_url
    max_choices: 1

# Provenance and supporting material
resources:
  original_skill:
    path: SKILL.before.md
    role: source_material
    description: Original prose-only browser research skill.
    used_by:
      - kind: route
        id: browser

# Which decision events to persist
trace:
  mode: event_log
  required: true
  record:
    - input_received
    - rule_matched
    - route_selected
    - elicitation_requested
    - outcome_recorded

# Scenario-based expectations the CLI can run
tests:
  - name: browse task uses browser
    input: browse https://example.com and take a snapshot
    expect:
      route: browser
      forbid_exact:
        - native_search_as_answer
      elicit_exact:
        - target_url
      matched_rules_exact:
        - browser_tasks_use_browser

Key sections

Routes are the candidate execution paths your skill knows about. Each route has a stable id, a human label, and an optional rank — lower rank means earlier default preference when no rule has made a selection.Routes can also carry a tool_boundary that restricts which tools the agent may call while executing that path, and checks — a list of command ids that must pass before the route is considered live.
routes:
  - id: durable_domain_handoff
    label: Hand off domain work and return for durable closure
    rank: 1
    tool_boundary:
      default: deny
      allow:
        - skillspec_cli
        - rote_exec
Rules are the conditional steering layer. Each rule has an optional when predicate and a set of additive effects: prefer sets the selected route, route_order replaces the current ordering, forbid unions forbidden substitutions, elicit appends clarifying questions, and after_success schedules post-task closures.Rules are evaluated in file order. The effects compose additively — every matched rule contributes to the same running decision state.
rules:
  - id: durable_memory_tasks_start_at_meta_router
    when:
      user_says_any:
        - remember this
        - future recall
        - trace and alignment
    prefer: durable_domain_handoff
    forbid:
      - direct_cli_without_rote_exec
    after_success:
      - compute_workspace_trace
      - run_skillspec_trace_alignment
    reason: Requests that ask for memory or trace should start at durable-executor.
Elicitations are bounded questions. Instead of guessing or asking open-ended questions, the skill declares a specific choice point with typed options. Each choice can set named facts, steer to a specific route, or advance to a named state.Elicitations do not execute commands by themselves — they surface a decision for the human or agent to make.
elicitations:
  install_scope:
    question: How should missing local tools be provisioned?
    required_when:
      - route: dependency_preflight
      - missing: dependency_install_scope
    max_choices: 1
    choices:
      - id: rote_managed
        label: Rote-managed or project-local
        sets:
          dependency_install_scope: rote_managed
        route: dependency_preflight
        safety: local_write
      - id: leave_draft
        label: Leave flow in draft
        sets:
          dependency_install_scope: none
        safety: read_only
Dependencies declare every tool, file, environment variable, service, adapter, or browser capability that commands and routes need. They don’t grant permission to install or run anything — they give the harness a concrete preflight checklist.The CLI can check cli, file, and env dependencies directly. package, service, adapter, and browser dependencies are harness-specific and appear in reports as requiring harness checks.
dependencies:
  gh:
    kind: cli
    description: GitHub CLI for repo and issue work.
    command: gh
    check:
      command: gh
    permission:
      required: true
      reason: GitHub CLI uses authenticated account state.
      safety: network_read
    provision:
      elicit: install_scope
      options:
        - id: user_global
          label: Install GitHub CLI with a user package manager
          command: brew install gh
          safety: local_write
The trace section declares which decision events the evaluator should persist. Setting required: true means a conforming harness must either write the trace or state that tracing is unavailable before relying on the decision.When record is empty or absent, an evaluator may record every v0 event kind.
trace:
  mode: event_log
  required: true
  record:
    - input_received
    - spec_loaded
    - rule_evaluated
    - rule_matched
    - route_selected
    - forbid_added
    - elicitation_requested
    - after_success_scheduled
    - outcome_recorded
Tests are scenario-based expectations — the primary proof mechanism for route decisions. Each test pairs a plain-text input with expectations over the decision: route selected, matched rules, forbidden substitutions, requested elicitations, and scheduled closures.Expectations use three forms: plain list (assert inclusion), *_exact (assert the exact set), and not_* (assert absence).
tests:
  - name: browse task uses browser
    input: browse https://example.com and take a snapshot
    expect:
      route: browser
      forbid_exact:
        - native_search_as_answer
      elicit_exact:
        - target_url
      matched_rules_exact:
        - browser_tasks_use_browser
The proof section names the metrics the contract is trying to improve — steering accuracy, forbidden-substitution coverage, captured-artifact completeness, and similar measures. These become the targets for alignment reports.
proof:
  metrics:
    - route_decision_accuracy
    - forbidden_substitution_coverage
    - captured_artifact_completeness

What the CLI validates

Running skillspec validate skill.spec.yml performs a set of structural and cross-reference checks without invoking a model:
  • Every Rule.prefer references an existing Route.id
  • Every Rule.elicit item references an existing elicitation
  • Every Test.expect.route references an existing route
  • Every Trace.record item is one of the v0 trace event kinds
  • Every Command.requires.dependencies item references an existing dependency
  • The import dependency graph is acyclic (checked with skillspec imports check)
  • No declared resource is orphaned — every resource without incoming references must declare used_by
  • Unknown fields are rejected (the schema is strict and fail-closed)
The full adoption gate before relying on a contract looks like this:
skillspec validate skill.spec.yml
skillspec imports check skill.spec.yml
skillspec test skill.spec.yml
skillspec deps check skill.spec.yml
Typed v0 objects are strict: unknown fields are invalid, so a misspelled behavior field silently disappearing is a validation error, not a silent no-op.

Relation to SKILL.md

The contract doesn’t replace the prose in SKILL.md. It structures the load-bearing decisions that prose alone hides inside paragraphs.
SKILL.md handlesskill.spec.yml handles
Tone, context, domain judgmentRoutes, rules, forbidden substitutions
Examples and explanationsDependencies and preflight checks
Human-readable proceduresElicitations and bounded questions
Background rationaleTests and scenario-based proof
Narrative flowTrace and alignment expectations
A skill with a valid contract still loads its SKILL.md prose at activation. The contract makes the critical decisions inspectable alongside that prose — not instead of it.
A good contract captures the behavioral load-bearing parts: the choices that could go wrong silently if a model improvises. Straightforward prose explanations can stay in prose.

Build docs developers (and LLMs) love