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:
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: filesargs: [read, ./a.txt] |
runtime files write ./a.txt hello |
provider: filesargs: [write, ./a.txt, hello] |
runtime github repo view cli/cli |
provider: githubargs: [repo, view, cli/cli] |
runtime github repo list acme per_page=100 |
provider: githubargs: [repo, list, acme, per_page=100] |
runtime command run gh repo list --limit 10 |
binary: ghargs: [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:
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:
- Run
runtime --output json capability authoring-contextand use its installed contract paths/digests and exact selected source. Ifauthoring_readyis false, report the reason; never fall back to the first source or Runtime Home cache. - Run
runtime capability listand reuse or extend a definition when one already serves the outcome. - Ask for any missing target facts or required inputs. Never invent them.
- Write the Markdown under
selected_source.dirwith your own editor or agent file tools. Authoring is source editing, not a File Engine operation, and does not require afile_policy.write_rootsgrant. - Run
runtime capability validate <path>until its grammar and operation references are clean. - Run
runtime capability plan <path> --input key=valueuntil every step is allowed. Plan resolves substitutions, context and policy, but does not authenticate, execute, use the network, mutate or audit. - 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"]
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:
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:
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¶
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.