Skip to content

Capability Authoring Reference

The complete grammar and authoring rules. This mirrors <Runtime Home>/specs/capability-spec.md, which ships inside the binary and is refreshed with every version — when the two disagree, the file in your Runtime Home wins, because it describes the binary you actually have.

Your runtime carries its own contract

This site gets you installed, gets your first capabilities running, and explains how the pieces fit. Any Runtime command prepares the Home automatically; runtime bootstrap is the optional explicit report. Start at <Runtime Home>/RUNTIME-AGENT.md (the contract) and manifest.json (this binary's providers and operations). Specs and command cheatsheets for your installed version live in <Runtime Home>/specs/ and commands/. Read those for precise operational detail — they describe the binary you actually have. Come back here for concepts, upgrades, and anything not yet installed.

Operations must come from the published files and github surfaces (runtime files --help, runtime github --help, or manifest.json). An invented operation fails validation rather than running:

capability is invalid:
  - workflow[0]: "does not exist" is not an operation of provider "github"

The authoring loop is a contract: authoring-context → reuse or write through runtime files → validate → plan → review. Validation is not policy approval; a successful plan is not source admission or permission to execute. Publishing and execution are separate, explicit actions.

Writing your first capability?

Read Create a Capability instead — it walks the whole sequence in order, from finding operations to sharing the result. Come back here for the details.

Grammar

```runtime
version: v1

inputs:
  <name>:
    description: <plain-English description>
    required: true|false

workflow:
  - provider: <registered provider>
    args: [<operation word>, ..., <argument>, ...]

  - binary: <allowed binary>
    args: [<positional arg>, ...]
```
Key Level Required Meaning
version top yes Spec version this block was authored against
inputs top no Named parameters, referenced as ${name} in any step's args
workflow top yes Ordered list of steps, executed in order
provider step one of A registered Provider (github, files)
binary step one of A binary in allowed_binaries
args step yes Positional arguments, exactly as typed on the CLI
description input no What this input is for
required input no Whether execution refuses to run without it

Each step sets exactly one of provider or binary — never both, never neither.

These are the only keys

The parser rejects anything it does not recognize, naming the offending key and its line number.

transport: rest        ✗ not a key — the provider owns that decision
steps:                 ✗ it is `workflow:`
command:               ✗ from the retired command registry
capability:            ✗ there is no capability step

This strictness is the point. Before it, transport: rest on a step or steps: instead of workflow: validated clean while doing nothing — a file that looked correct and silently skipped its work.

args are the CLI, sequenced

A step's args are exactly the words you would type after runtime <provider>, split into a list.

On the command line In a capability
runtime files read ./a.txt provider: files
args: [read, ./a.txt]
runtime files write ./a.txt hello provider: files
args: [write, ./a.txt, hello]
runtime github repo view cli/cli provider: github
args: [repo, view, cli/cli]
runtime github repo list acme per_page=100 provider: github
args: [repo, list, acme, per_page=100]
runtime command run gh repo list --limit 10 binary: gh
args: [repo, list, --limit, "10"]

This is the same surface, just sequenced inside a file instead of typed one command at a time.

Discovering operations

Do not guess at operations. Every provider publishes its full surface, and that published list is the authority:

runtime github --help
runtime files --help

The same list is on disk at <Runtime Home>/manifest.json, generated from the registry that executes, so an assistant with no network still has the correct surface. <Runtime Home>/RUNTIME-AGENT.md is the vendor-neutral contract for this binary — two providers, files and github; everything else in commands/ is a Command Engine pass-through.

The help output lists every operation, its argument form, and the transport the provider chose for it. The transport column is information, not a choice.

runtime capability list     # what this install can already resolve
runtime capability validate ./my-capability.md

A successful validate is the document/compatibility gate before runtime github file put. It is not source admission and not permission to execute.

Reliable one-ask authoring

For every human or AI authoring session:

  1. Run runtime --output json capability authoring-context and use its installed contract paths/digests and exact selected source. If authoring_ready is false, report the reason; never fall back to the first source or Runtime Home cache.
  2. Run runtime capability list and reuse or extend a definition when one already serves the outcome.
  3. Ask for any missing target facts or required inputs. Never invent them.
  4. Write the Markdown under selected_source.dir with your own editor or agent file tools. Authoring is source editing, not a File Engine operation, and does not require a file_policy.write_roots grant.
  5. Run runtime capability validate <path> until its grammar and operation references are clean.
  6. Run runtime capability plan <path> --input key=value until every step is allowed. Plan resolves substitutions, context and policy, but does not authenticate, execute, use the network, mutate or audit.
  7. Show the path, source, digest, diff and plan. Commit/publish only on an explicit request; execute only as a separate explicit action.

Identity allow-list evaluation is deferred during plan because identity is intentionally resolved only during execution. That does not weaken execution: the full auth and identity checks still apply then.

Pushing a new file

Author into the exact directory capability authoring-context reports, never silently into Runtime Home. Since 0.9.2 that is normally the one directory named by RUNTIME_CAPABILITIES_DIR, with nothing configured first; write the file with your own editor or agent.

Publishing is a later explicit action, and remains governed — the push is:

runtime github file put owner/repo capabilities/my-cap.md \
  message="Add my-cap" content="$(cat ./my-cap.md)"

The provider UTF-8/base64-encodes content. Do not hand-build github api PUT …/contents/…. Omit sha to create-only; pass sha=<blob> to compare-and-set.

The rules

1. Never hardcode auth

Every step already goes through the Auth Engine via the provider or binary it names. A capability never embeds a token, credential, or auth flow of its own.

2. Never assume a Runtime Context beyond what's active

If a workflow genuinely needs a specific org, project or namespace, declare it as an input:

inputs:
  organization:
    description: GitHub organization to audit
    required: true

workflow:
  - provider: github
    args: [repo, list, "${organization}"]

Nothing falls back to a Runtime file. A value the workflow cannot invent — an organization, a project, a namespace — is a declared input, and Runtime supplies none of them on your behalf. A value that really is where you are rather than what this run is about comes from the native tool: leave it out of the capability and let kubectl or gcloud decide.

3. Ask when a required input is missing

Don't invent a placeholder and execute anyway. capability execute refuses to run with a missing required input; respect that at authoring time too.

4. Only reference what the runtime can execute

A step's provider must be registered and its args must name a real operation of that provider. A binary must already be in allowed_binaries.

5. Never depend on a transport

Write provider: github / args: [repo, list], never "the REST one". If you need a specific wire protocol, the provider is missing an operation — add the operation.

6. Don't finish until inputs are resolved

A capability referencing ${organization} isn't done until the author knows where that value comes from.

Input substitution

${name} substitution is literal text replacement, performed before execution.

inputs:
  path:
    description: Where to write
    required: true

workflow:
  - provider: files
    args: [write, "${path}", "hello"]
runtime capability execute my-cap --input path=./notes.txt

An unsupplied optional input stays literal

An input you declare but do not supply remains in the arguments as the literal string ${name}. That is why every shipped example marks its inputs required: true. Prefer required: true unless you have a concrete reason not to.

Passing a tool's own flags

Because a CLI-backed operation forwards arguments verbatim, a capability may pass that tool's own flags — including output flags:

- provider: github
  args: [pr, list, --json, "number,title,state"]

This is not naming a transport. You are passing arguments the operation accepts; the provider still owns how it delivers them.

For the runtime's own output format, use the global flag at execution time rather than inside the file:

runtime --output json capability execute my-cap --input ...

Composition: there is no capability: step

A capability cannot invoke another capability. There is no capability: step, and runtime is not an allowed binary — so a binary: runtime step fails validation too.

Large workflows inline the smaller ones they re-derive, and declare a Lineage section in the prose naming what was inlined:

## Lineage

Re-derives:
- `github/repo-health` — steps 3–5
- `files/scaffold-service-docs` — steps 9–12

The prose has no effect on execution. It exists so a reader can tell what a long workflow was assembled from, and so a change to a source capability has a findable set of dependents.

Worked example

Turning an ad-hoc audit into a capability:

# Repository standards audit

Answers "what do we own, and does this repo meet standard?"

## Lineage

Re-derives `github/repositories` for step 1.

```runtime
version: v1

inputs:
  organization:
    description: GitHub organization to audit
    required: true
  repository:
    description: Repository to inspect, as <owner>/<repo>
    required: true

workflow:
  - provider: github
    args: [repo, list, "${organization}", per_page=100]

  - provider: github
    args: [repo, summary, "${repository}"]

  - provider: github
    args: [api, GET, "/repos/${repository}/community/profile"]
```
runtime capability validate ./audit.md
runtime capability execute ./audit.md \
  --input organization=my-org \
  --input repository=my-org/orders-api

Note what the capability does not say: which transport serves each step. Step 1 happens to go over REST, step 2 over GraphQL, step 3 over REST — the provider decides, and can change its mind in a later runtime version without breaking this file.

Known limitations

Worth knowing before you design around them:

Limitation Consequence
No mkdir operation files write fails when parent directories are missing — create the path some other way first
files delete denied by default policy Use git rm for recoverable removal, or change policy deliberately
No encoding primitive Base64 payloads must be written literally in the file
Execution stops at the first failure Capabilities are not transactional — earlier steps have already run
No loops, no conditionals, no branching A capability is an ordered list. Complexity belongs in what you compose, not in control flow
No capability-to-capability calls Inline and declare Lineage

These are properties of a deterministic execution format, not a backlog. A workflow that needs branching is usually two capabilities and a decision.

Validation

runtime capability validate <path|name>

Reports every problem found, not just the first. See Validate & Execute.

Operational examples on this site were verified against Runtime 0.9.8. After bootstrap, the version-exact files in Runtime Home win.