Schemas
The components only this tag's operations use. Each row is the type's own field, its doc comment the description; a type another page owns links there.
BenchmarkPolicy
one of 3 variants
Whether the capability is a benchmark target. Required is the default and the norm:
every executable capability is timed directly and through every transport it is
exposed on, with the cases its input type provides.
variant Timed directly and through every exposure; coverage fails without a case.
variant Required exactly like Required in a repository where the precondition holds, and
reported as inapplicable — never covered, never waived — where it does not. Not a
waiver: with the precondition met and no case, the requirement is missing.
| precondition | BenchmarkPrecondition → BenchmarkPrecondition | yes | What the repository must hold. |
| policy | "required_when" | yes | |
variant Not timed, for the typed reason; coverage reports it as waived, never as covered.
Used by Capability CapabilitySummary
BenchmarkPrecondition
"plan_holds_an_issue"
What a repository must hold before a conditional benchmark requirement applies to it.
Typed, like a waiver's reason, so that the condition is a reviewable statement on the
descriptor and never a provider quietly returning nothing.
use majordomus_cli::capability::BenchmarkPrecondition;
let p: BenchmarkPrecondition = serde_json::from_str(r#""plan_holds_an_issue""#).unwrap();
assert_eq!(p, BenchmarkPrecondition::PlanHoldsAnIssue);
plan_holds_an_issueThe plan holds at least one issue. A command whose every honest case is a refusal
chosen from an issue's own status has no such refusal in a plan with no issue: the
only answer there is a lookup miss, which times an error path and is not the
operation.
Used by BenchmarkPolicy
CachePolicy
one of 4 variants
Whether, and how, the executor keeps results of this capability. Cache lives in the
executor and nowhere else, so MCP, HTTP and the command line share one; the key is the
canonical id, the normalised input and the registry fingerprint, so a changed
repository never answers from an old entry. The two narrower policies add to the key
what the registry fingerprint cannot see: the context's own reading of the repository
(CachePolicy::Generation) and the state of the checkout itself
(CachePolicy::Checkout).
variant Every call runs the handler.
variant Results are kept in this process's memory, bounded, for equal inputs.
| max_entries | integer (uint) | yes | The most entries kept for this capability; the oldest is evicted first. |
| ttl_seconds | integer | null | no | Seconds an entry stays valid; None for the life of the process. |
| policy | "process" | yes | |
variant Results are kept for equal inputs while the context that computed them is the one
asked: for a capability that is a function of the index and the registry alone,
including the git state the index was read at, which the registry fingerprint does
not cover. A reload of the repository is a new context, and so a new key.
| max_entries | integer (uint) | yes | The most entries kept for this capability; the oldest is evicted first. |
| policy | "generation" | yes | |
variant Results are kept for equal inputs while the context is the same and the checkout
is as it was: HEAD, the staging index, the refs and every changed or untracked path
of the work tree, fingerprinted again on every call
(capability::checkout). For a capability that reads git, the index and the
files of the work tree, and nothing that fingerprint cannot see: no ignored file, no
other process, no network, no clock. A checkout git cannot fingerprint is not cached.
| max_entries | integer (uint) | yes | The most entries kept for this capability; the oldest is evicted first. |
| policy | "checkout" | yes | |
Used by Capability CapabilitySummary
CanonicalSchema
object
A JSON Schema with, when the type has one, a stable component name (the type's title).
| property | type | required | description |
| name |
string | null |
no |
The component name projections use (RepositoryInfo); None for an anonymous
schema such as the empty input. |
| schema |
any |
yes |
The schema itself, without $schema; nested types live under $defs. |
Used by Capability
Capability
object
The canonical descriptor. Everything a projection may say about a capability is here.
| property | type | required | description |
| id |
CapabilityId → CapabilityId |
yes |
The canonical identity. |
| module |
ModuleId → ModuleId |
yes |
The module that composes it: the id's namespace for a builtin, the kind for a
declarative object. |
| kind |
CapabilityKind → CapabilityKind |
yes |
Query, command or resource. |
| title |
string |
yes |
The short name every projection shows. |
| description |
string |
yes |
The one-paragraph description every projection shows. |
| input |
CanonicalSchema → CanonicalSchema |
yes |
The canonical schema of the input; an empty object for a resource. |
| output |
CanonicalSchema → CanonicalSchema |
yes |
The canonical schema of the output; the object view for a resource. |
| provenance |
CapabilityProvenance → CapabilityProvenance |
yes |
Where it came from. |
| exposure |
Exposure → Exposure |
yes |
Where it is projected; absence is explicit. |
| availability |
CapabilityAvailability → CapabilityAvailability |
yes |
Where it means anything: classified from the kind and the transports above, so
that a projection reads a field instead of deciding for itself. |
| visibility |
CapabilityVisibility → CapabilityVisibility |
yes |
Who it is for: classified from the same transports. |
| stability |
Stability → Stability |
yes |
Where it stands. |
| tags |
array of string |
no |
Free tags, from the declarative object's tags or the descriptor. |
| benchmark |
BenchmarkPolicy → BenchmarkPolicy |
yes |
Whether it is a benchmark target; the cases come from the input type. |
| cache |
CachePolicy → CachePolicy |
yes |
Whether the executor keeps its results. |
| execution |
ExecutionPolicy → ExecutionPolicy |
yes |
What running it as an execution means: classified from the kind, so that a client
reads a fact rather than deciding for itself. |
| skill |
SkillExposure | null → SkillExposure |
no |
The short name a person invokes it by from an agent's prompt, when it has one. |
Used by capabilities.describe
CapabilityAvailability
"always" | "runtime" | "build_time" | "authenticated"
Where a capability means anything: the environment a caller must be in for it to
answer at all.
The published site and the running server are genuinely different places. Without this
on the model, every template grows its own idea of what works where — and the usual
shape that takes is a condition on the page's own address, which is a rule hidden
where nobody will find it and nothing can test it. This is the only thing a projection
may ask.
It is classified rather than declared: the facts that decide it — what kind of thing
this is and which transports it is projected through — are already on the descriptor,
and asking each declaration to restate them would be the same knowledge written twice.
Availability::classify is the one place the rule lives.
alwaysTrue in every environment, a published page with no server included: the layer's
own content, which a build renders and a process serves from the same index.runtimeA process must be running to answer: everything with a handler, whether it is
reached over HTTP, over MCP or from the command line.build_timeA value captured when the site was generated, rendered afterwards as the capture
it is. Nothing classifies to this yet; the static projection of the graph is what
will declare it, and it is on the model so that a captured value can be labelled
as captured instead of being shown as current.authenticatedA process must be running and the caller must be one it has authenticated. Nothing
in this repository authenticates a caller yet; a surface that does will say so
here rather than in the template that renders its link.
Used by Capability
CapabilityList
object
The answer of capabilities.list: the matching capabilities, summarised, and the
registry counted.
| property | type | required | description |
| count |
integer (uint) |
yes |
How many capabilities matched the filters. |
| summary |
Summary → Summary |
yes |
The whole registry, counted by kind, stability and projection. |
| capabilities |
array of CapabilitySummary → CapabilitySummary |
yes |
The matching capabilities, by id, without their schemas. |
Used by capabilities.list
CapabilitySummary
object
One capability as a listing shows it: everything the descriptor says except its two
schemas, which capabilities.describe answers for one capability. A listing of a
repository's registry runs to hundreds of entries; their schemas would be megabytes
of the same object view repeated.
| property | type | required | description |
| id |
CapabilityId → CapabilityId |
yes |
The canonical identity. |
| module |
ModuleId → ModuleId |
yes |
The module that composes it. |
| kind |
CapabilityKind → CapabilityKind |
yes |
Query, command or resource. |
| title |
string |
yes |
The short name. |
| description |
string |
yes |
The one-paragraph description. |
| provenance |
CapabilityProvenance → CapabilityProvenance |
yes |
Where it came from. |
| exposure |
Exposure → Exposure |
yes |
Where it is projected. |
| stability |
Stability → Stability |
yes |
Where it stands. |
| tags |
array of string |
no |
Free tags. |
| benchmark |
BenchmarkPolicy → BenchmarkPolicy |
yes |
Whether it is a benchmark target. |
| cache |
CachePolicy → CachePolicy |
yes |
Whether the executor keeps its results. |
Used by CapabilityList
CapabilityVisibility
"public" | "developer" | "internal"
Who a capability is for, and whether anything offers it.
Internal is a statement, not an omission: a capability nothing projects is invisible
either way, and the difference between deliberate and forgotten is exactly what this
records.
publicOffered to anyone who can reach the process: an HTTP route or an MCP entry.developerOffered to whoever runs the executable, and to nobody over a network.internalProjected nowhere. It exists, it is listed as existing, and no surface offers it.
Used by Capability
CliExposure
object
How a capability appears on the command line: the words after majordomus.
| property | type | required | description |
| path |
array of string |
yes |
The words after majordomus, e.g. ["capabilities", "list"]. |
Used by Exposure
ClosureMatrix
object
The whole matrix, with the findings and the debt beside it: one value that answers
"where does each capability appear, and is any claim unmet".
| property | type | required | description |
| rows |
array of Row → Row |
yes |
One row per capability, in id order. |
| unbacked |
array of string |
yes |
Runnable commands of the command line that no capability claims, in command order. |
| unclassified |
array of string |
yes |
Of those, the ones crate::cli::local::LOCAL does not explain either: a command
that is neither the projection of a capability nor declared command-line-only with
a reason. Empty is the closure the rule asks for; anything here is an operation
that left the API by accident rather than by decision. |
Used by capabilities.projections
ExecutionConcurrency
"unrestricted" | "serial"
Whether two executions of one capability may overlap.
unrestrictedAny number at once. Every read is one of these: the index and the registry are
immutable for the life of the process, so concurrent readers cannot interfere.serialOne at a time. A second execution of the same capability waits for the first, which
is what a capability that changes anything — this process's own memory included —
needs in order to be reasoned about at all.
Used by ExecutionPolicy
ExecutionPolicy
object
What running a capability as an execution means: what it changes, whether asking it to
stop achieves anything, and whether two of them may overlap.
The effect and the concurrency are classified from the kind by
ExecutionPolicy::classify, for the same reason Availability is: the facts are
already on the declaration, and asking each capability! block to restate them would be
one more thing that can disagree with itself.
Cancellability is the one thing the kind cannot decide, because it is a fact about the
handler: whether it looks at its cancellation flag and stops. A handler that does says
so with crate::capability::Executable::cancellable, and a client is then told
whether a Cancel button will achieve anything instead of being given one that lies.
| property | type | required | description |
| effect |
ExecutionEffect → ExecutionEffect |
yes |
What it changes. |
| cancellable |
boolean |
yes |
Whether asking it to stop does anything. A task looks at its cancellation flag; a
query and a command do not, and a client is told so rather than being given a
button that lies. |
| concurrency |
ExecutionConcurrency → ExecutionConcurrency |
yes |
Whether two of them may overlap. |
| signed_input |
boolean |
no |
Whether the input authenticates its caller.
A handler whose input is a signed message, and which verifies the signature against
the trust policy before anything changes, admits its caller by that signature and not
by the address the request came from. Only such a handler changes state for a caller
on another host; see ExecutionPolicy::admits_remote. |
Used by Capability
Exposure
object
The projections a capability declares. Absence is explicit: None means not exposed
there, and nothing infers an exposure a descriptor did not declare.
| property | type | required | description |
| mcp |
McpExposure | null → McpExposure |
no |
The MCP projection, when declared. |
| http |
HttpExposure | null → HttpExposure |
no |
The HTTP projection, when declared. |
| cli |
CliExposure | null → CliExposure |
no |
The command-line projection, when declared. |
Used by Capability CapabilitySummary
HttpExposure
object
How a capability appears over HTTP. GET binds every top-level input property as a
query parameter; POST binds the input as the JSON request body. Paths are absolute
and live under HttpExposure::PREFIX.
| property | type | required | description |
| method |
HttpMethod → HttpMethod |
yes |
The method. |
| path |
string |
yes |
The absolute path, under HttpExposure::PREFIX. |
Used by Exposure
HttpMethod
"GET" | "POST"
The HTTP methods a capability may be bound to.
GETRead-only; the input is bound from the query string.POSTThe input is bound from the JSON body. Every mutating capability uses it.
Used by HttpExposure
McpExposure
object
How, if at all, a capability appears to an MCP client.
| property | type | required | description |
| tool |
string | null |
no |
As a tool with this name ([a-z0-9_]+). |
| resource |
McpResource | null → McpResource |
no |
As a readable resource. |
Used by Exposure
McpResource
object
An MCP resource: its URI and the short name a client lists.
| property | type | required | description |
| uri |
string |
yes |
majordomus://<kind>/<identity>, or majordomus://repository. |
| name |
string |
yes |
The short name a client lists; the identity for a declarative object. |
Used by McpExposure
ModuleId
string
A module identity: the namespace of every capability the module composes, matching
[a-z][a-z0-9_-]*. Builtin modules declare theirs in module!; a declarative
object's module is its kind.
Used by Capability CapabilitySummary
Row
object
Where one capability is projected, and where it is not.
This is the coverage matrix of the rule: a row per capability, a column per interface.
It is derived, never written down — a capability that reaches nothing shows as a row of
false, which is exactly the "exists but is invisible" case worth seeing.
| property | type | required | description |
| id |
string |
yes |
The canonical id. |
| module |
string |
yes |
The module that composes it. |
| kind |
string |
yes |
Query, command or resource. |
| stability |
string |
yes |
Where it stands. |
| effect |
ExecutionEffect → ExecutionEffect |
yes |
What a call changes: nothing, this process's memory, or the repository. The same
classification every projection reads, so the matrix answers "where is it reachable"
and "what does reaching it risk" in one row. |
| cli |
string | null |
no |
The command line, when it declares one and clap has it. |
| http |
string | null |
no |
The HTTP route, when it declares one. |
| mcp_tool |
string | null |
no |
The MCP tool name, when it declares one. |
| mcp_resource |
string | null |
no |
The MCP resource URI, when it declares one. |
| closed |
boolean |
yes |
Whether every exposure this row declares is answered by its surface. |
| source |
string |
yes |
Where the capability is declared; repository-relative. |
Used by ClosureMatrix
SkillExposure
object
A capability as a skill a person invokes by a short name from an agent's prompt:
/intent <sentence> in Claude Code. The name and the one input field the typed text
fills are declared here, once; the file an agent product reads is generated from them
(the
editors module) and carries no description of what the capability does beyond
the capability's own.
use majordomus_cli::capability::SkillExposure;
let s = SkillExposure { alias: "intent".into(), argument: "statement".into() };
assert!(s.validate().is_ok());
// a name an agent product already owns is refused, and so is one that is not a name
let taken = SkillExposure { alias: "review".into(), argument: "x".into() };
assert!(taken.validate().unwrap_err().contains("reserved"));
let shouted = SkillExposure { alias: "Intent".into(), argument: "x".into() };
assert!(shouted.validate().is_err());
| property | type | required | description |
| alias |
string |
yes |
The name typed after the slash: lowercase letters, digits and hyphens, at most 64. |
| argument |
string |
yes |
The input field the text typed after the name fills, verbatim. |
Used by Capability
WaiverReason
"not_executable" | "destructive" | "external_dependency" | "transient_state" | "published_history"
Why an executable capability is not benchmarked. Typed, so that a waiver is a
reviewable statement and never a convenience; not_executable is the registry's own
reason for resources and is never written by hand.
not_executableA resource: read, never executed; nothing to time but objects.get, which is.destructiveThe capability changes something outside this process and cannot be run in a loop.external_dependencyThe capability talks to something the benchmark host cannot provide.transient_stateThe capability starts, or answers about, work that exists only while it is running.
A benchmark host cannot stage an execution to read, and running the operation in a
loop would measure the work rather than the operation.published_historyThe capability answers about what this repository has published, so its input is a
release: a version tag, the commit it points at, and the projection committed there.
A benchmark fixture is a repository that has published nothing, and the honest answer
in one is a refusal — so the case would time an error path and call it coverage.
Distinct from WaiverReason::ExternalDependency: nothing outside this process is
consulted, and distinct from WaiverReason::TransientState: the history is durable,
it simply does not exist yet where the benchmark runs.
Used by BenchmarkPolicy