Contract format
The agentspec/v1 contract — metadata, instructions, schemas, tools, guardrails, and permissions.
A contract project is a directory with a top-level agent.yaml (the contract),
an optional README.md, and supporting files under schemas/, tools/,
guardrails/, and examples/. Everything in those locations is uploaded as
the project's draft when you unispec validate / unispec publish.
agent.yaml
apiVersion: agentspec/v1
kind: Agent
metadata:
name: support-triage
version: 1.0.0
instructions:
system: |
You are a support triage agent. Classify the incoming message and pick a tool.
input:
schema:
type: object
required:
- message
properties:
message:
type: string
description: The customer message.
priority:
type: string
description: Optional priority hint.
output:
schema:
type: object
required:
- category
properties:
category:
type: string
description: The triage category.
next_action:
type: string
description: Suggested next action.
tools:
- ref: tool://crm.lookup_customer
- ref: tool://kb.search
guardrails:
input:
- ref: guardrail://input.relevance-check
output:
- ref: guardrail://output.sensitive-info
security:
permissions:
- crm:read
- kb:readFields
| Field | Required | Meaning |
|---|---|---|
apiVersion | yes | Contract schema version — agentspec/v1. |
kind | yes | Agent (the only kind in v1). |
metadata.name | yes | Contract name (matches the project by convention). |
metadata.version | yes | Semver of the contract content. |
instructions.system | yes | The agent's system prompt / behavior description. |
input.schema | yes | JSON-Schema-style object describing the agent's input. |
output.schema | yes | JSON-Schema-style object describing the agent's output. |
tools[].ref | no | Tool references in tool://<namespace>.<name> form. |
guardrails.input[].ref / guardrails.output[].ref | no | Guardrail references in guardrail://<name> form; each must match a spec under guardrails/. |
security.permissions | no | Declared permission strings the agent needs. |
Guardrails
A guardrail is a reusable validation/gating contract, defined as its own
first-class spec under guardrails/ and referenced from the agent by stage:
# guardrails/input.relevance-check.yaml
kind: Guardrail
metadata:
name: input.relevance-check
version: 1.0.0
spec:
stage: input # input | output | tool_input | tool_output | conversation | retrieval_context
mode: llm_classifier # deterministic_rule | llm_classifier | llm_evaluator | schema_check | policy_check
effect: block # block | warn | score | annotate | route
instructions: |
Determine whether the user message is relevant to customer support.
decision:
allow_values: [relevant]
blocking_values: [not_relevant]Validation checks the closed stage/mode/effect value sets, requires a
decision.blocking_values list on blocking guardrails, verifies every agent
guardrail:// ref resolves to a spec in guardrails/, and warns on unused
specs or stage mismatches. Generated artifacts include the guardrail
manifests — the unispec-agents target groups them by stage so the platform
runtime can wire its input/output guards from the contract.
Validation
unispec validate (and every publish) runs the validation engine over the
draft:
- Structure — required files present, YAML/JSON parseable, required
top-level fields, supported
apiVersion/kind. - Schemas — input/output schemas are structurally valid;
requiredfields must exist inproperties; unsupported combinators are rejected. - Tools —
tool://references are well-formed and consistent. - Guardrails —
guardrail://references resolve toguardrails/specs; stage/mode/effect values are valid; blocking guardrails declareblocking_values. - Quality & metadata — warnings for missing descriptions, README, etc.
- Compatibility — generator compatibility flags, and breaking-change
detection against a published version on
unispec diff(e.g. removed output fields, newly-required inputs, input type changes, tool or guardrail removals and swaps).
Issues carry a severity; errors block unispec publish, warnings don't.
Versioning
Published versions are immutable. Bump metadata.version (and pass
--version) for every publish; use unispec diff --against <version> to
review changes — additive changes are safe, removals and type changes are
flagged as breaking.
A published version can be deprecated — unispec deprecate 1.0.0 --reason "use 2.x" (undo with unispec undeprecate 1.0.0). Deprecation is
advice to consumers, not a removal: the version stays published, pullable,
and served; the registry UI and API flag it with the reason.