Skip to content

A capability is invoked by name through a generated skill

A capability is invoked by name through a generated skill

majordomus://adr/adr-0146accepted capabilitiesproviderseditors

it references

  • put_in_force apps/majordomus-cli/src/capability/model.rs (file)
  • put_in_force apps/majordomus-cli/src/editors/claude.rs (file)
  • put_in_force adr-0004
  • put_in_force adr-0140
  • put_in_force adr-0144
  • put_in_force docs/EDITORS.md (document)
  • put_in_force test/cases/2980_a_capability_is_invoked_by_name_from_claude_code.sh (test)

referenced by

146. A capability is invoked by name through a generated skill

Context

A capability is declared once and projected to the command line, MCP, HTTP and OpenAPI (ADR 0004). An agent's user reaches it through the MCP tool, which means describing what they want and letting the model find the tool. The owner asked for the short form: /intent <sentence> in Claude Code, with nothing registered by hand and no copy of what the capability does.

Claude Code reads a project's skills from .claude/skills/<name>/SKILL.md, and a skill is also a command: /<name> <text> loads it with the text in place of $ARGUMENTS. ADR 0140 already projects the layer's workflow skills for Zed and Antigravity through one plan, with ownership by banner, refusal of hand-written files and removal of orphans.

Decision

A capability may declare a skill: an alias and the one input field the typed text fills. The declaration is .skill(alias, argument) on the capability, beside .writes_repository(). It is typed descriptor metadata (Capability.skill), absent for every capability that does not say it.

The registry holds the skill to the capability. It refuses an alias that is not a name agent products accept, one an agent product already answers to (a reserved list), one another capability took, an argument that is not a string field of the input, and an input that requires another field the typed text cannot supply.

The file is generated by the editors plan, as one more adapter (claude-code). It carries the front matter Claude Code requires, the banner, the capability's id, where the text goes, and how the capability is reached: its MCP tool, else its command line. It says nothing about what the capability does beyond the declaration's own title. A capability whose effect is not read is projected with disable-model-invocation: true, so only a person invokes it, and the file tells the agent to call it once and not to retry a refused or unknown outcome by another way.

Coverage is not one file per capability. Every capability with an MCP tool is already reachable from Claude Code. A skill is for the few a person types by name.

Alternatives rejected

A hand-written .claude/commands/intent.md. It is a second description of the capability that nothing holds to the first.

An MCP prompt per capability. Claude Code splits a prompt's arguments on whitespace, so a sentence does not arrive as one value.

One skill per capability. Hundreds of names in the listing, each a restatement of a tool the model can already call.

Consequences

  • /intent <sentence> calls intents.propose with the sentence as its statement. It was run with the installed client (Claude Code 2.1.296) against a fresh repository: the record was written through the MCP tool, and with the tool not permitted the client reported the refusal and did not fall back to the command line.
  • majordomus generate writes the skill, generate --check fails when it is stale, and a capability that drops its alias has its file removed as an orphan.
  • editors.status reports the claude-code adapter with its evidence, beside Zed and Antigravity.
  • Argument inference, transport selection by a dispatcher, and recording the call as an execution are later steps; this one makes a capability reachable by name.

Where this comes from

canonical file
.ai/repo/adrs/0146-a-capability-is-invoked-by-name-through-a-generated-skill.md
identity
adr-0146
also served as
MCP resource majordomus://adr/adr-0146 · majordomus entity show adr/adr-0146 · GET /api/v1/entity?uri=majordomus://adr/adr-0146
in the Cockpit
/cockpit/objects/adr/adr-0146

This page is generated from the file above by scripts/generate-site-data; editing the page changes nothing, editing the file changes every surface. The relations above are edges of docs/generated/graph.json, which the executable writes from the same index.

Searches the titles and descriptions of every page this site publishes.