#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum BuildError {
#[error(
"this plane runs as tenant '{plane}' but its blob store serves '{store}'. \
Blobs are content-addressed, so a shared store means two tenants' \
identical bytes are one object — and erasing it for one destroys it for \
the other while reporting both requests discharged"
)]
BlobStoreTenant { plane: String, store: String },
#[error(
"this plane runs as tenant '{plane}' but its journal store is scoped to \
'{store}'. The mismatch does not surface at runtime: runs are written \
into the other tenant's keyspace while every erasure and every policy \
request names this one"
)]
JournalStoreTenant { plane: String, store: String },
#[error(
"tool server 'agent' is reserved: `tool://agent/<capability>` names an \
agent on this plane and dispatches through `commission`. A transport \
under that name would let a deployment change whether a grant means \
\"an agent here\" or \"somebody's server\" without changing any \
reviewed document — rename the server"
)]
ReservedToolServer,
#[error(
"agent '{agent}' grants 'tool://agent/{capability}', and no agent on \
this plane provides '{capability}' — the model would be offered a \
consultation that fails when chosen"
)]
AgentToolUnknownCapability { agent: String, capability: String },
#[error(
"agent '{agent}' grants 'tool://agent/{capability}', which it provides \
itself — an agent consulting itself is a loop wearing a grant, and \
the delegation ceiling would only bound how long it spins"
)]
AgentToolSelfReference { agent: String, capability: String },
#[error(
"tool server '{server}' is registered twice — registration order would \
decide which transport carries a call"
)]
DuplicateToolServer { server: String },
#[error(
"this plane wires tools twice — `tools(..)` states the catalogue \
explicitly and `toolbox(..)` derives it from the agents, so one of them \
would silently replace the other's grants"
)]
ToolsWiredTwice,
#[error(
"the tools this binary implements and the manifest of agent '{agent}' \
disagree — the declaration a reviewer approved no longer describes the \
agent:\n {}", problems.join("\n ")
)]
ToolDrift {
agent: String,
problems: Vec<String>,
},
#[error(
"agents '{first}' and '{second}' both grant '{tool}' and declare it \
differently — a plane has one catalogue, so one of the two reviewed \
declarations would silently not be the one enforced"
)]
ToolDeclaredTwoWays {
tool: String,
first: String,
second: String,
},
#[error(
"tools were wired to a plane with no declared agent — a grant is an \
agent's declaration, so there is nothing here that admits them"
)]
ToolsWithoutDeclaration,
#[error(
"the stated tool catalogue is laxer than a reviewed manifest grant — a \
read-only entry exempts the tool from the whole-value taint gate and \
makes a timed-out call retryable:\n {}", problems.join("\n ")
)]
CatalogueLaxerThanGrant { problems: Vec<String> },
#[error(
"two skills on this plane are both named '{name}'. A skill name is how a \
capability resolves to an implementation and how a run names what it \
dispatched, so two of them make both answers arbitrary — rename one"
)]
DuplicateSkillName { name: String },
#[error(
"capability '{capability}' is claimed by two agents on this plane: \
'{first}' and '{second}'. Dispatch resolves a capability to one skill \
and to the manifest governing it, so the second claim would silently \
take the first's work out from under the first's budget and grants. \
Give them distinct capabilities, or put them on separate planes"
)]
CapabilityClaimedTwice {
capability: String,
first: String,
second: String,
},
#[error(
"agent '{agent}' declares execution but no privileged model — a \
declarative agent has nothing to call"
)]
DeclarativeWithoutModel { agent: String },
#[error(
"agent '{agent}' names provider '{provider}', which no driver is \
registered for. Call RuntimeBuilder::provider(\"{provider}\", ..)"
)]
UnknownProvider { agent: String, provider: String },
#[error(
"agent '{agent}' declares execution but provides no capability — a \
declarative agent nothing can call is a file that does nothing"
)]
DeclarativeProvidesNothing { agent: String },
#[error(
"agent '{agent}' advertises capabilities none of its own skills provide: \
{missing:?}. A skill wired with `RuntimeBuilder::skill` is not governed \
by any agent — it runs under the plane's budget and no manifest gate. \
Register it on the agent instead: \
`.agent(Agent::new(&manifest).skill(MySkill))`"
)]
AdvertisesWhatItCannotProvide { agent: String, missing: Vec<String> },
}