Conformance and spec
Reference
The agent3md/1 spec
agent.3md is defined by the agent3md/1 specification, layered on the base
3md format (3md: 1.0). The spec covers the
manifest frontmatter, the single identity plane versus skill planes, the skill
contract (triggers, typed inputs, tool command templates, cost, dependency
links), the loader contract (manifest / route / get / resolve /
command), and the conformance rules below.
The authoritative document is
SPEC.md in the
agent-3md repository.
What makes a document conforming
A document is a conforming agent3md/1 agent when:
- It is valid 3md (
3md: 1.0) and parses without error. - It has a name (
titleoragent).modelis an optional hint, not required. - It has exactly one identity plane (explicit
kind=identity, or the first plane by the fallback rule). All other planes are skills. - Every skill has a unique, non-empty name (its
label). - Every
[[z=N]]/[[z=N|label]]link targets an existing plane. - There are no dependency cycles among
[[z=N]]links. - If
entryis set, it is thezof a plane that exists. - Every declared input uses a canonical type (
string,number,boolean,object,array); a bare name is a requiredstring. - No skill declares the same input name twice.
- Every
{placeholder}in a skill'stoolcommand has a matching declared input.
A conforming loader must ignore unknown frontmatter keys and unknown plane attributes rather than failing, so the format can evolve additively.
The validator and its rules
The reference validator (validateAgent in TypeScript, mirrored in the Rust
loader) reports each problem against the offending plane's z. Errors fail the
document; warnings flag likely mistakes without failing.
Errors
| Rule | Triggered when |
|---|---|
parse | The document is not valid 3md. |
frontmatter | Missing the 3md: version line, or missing a name (title / agent). |
identity | More than one kind=identity plane (an empty document with no planes also fails here). |
missing-label | A skill plane has no label. |
unique-skill | Two skills share a label. |
dead-link | A [[z=N]] link points to a plane that does not exist. |
cycle | A [[z=N]] dependency chain forms a loop. |
entry | entry: is not an integer plane z, or does not resolve to a real plane. |
input-type | An input declares a type outside the canonical set. |
dup-input | A skill declares the same input name twice. |
tool-input | A command {placeholder} has no matching declared input. |
Warnings
| Rule | Triggered when |
|---|---|
triggers | A skill has no triggers, so it can never be routed to. |
tool | A skill sets tool= but leaves it empty. |
unused-input | A skill declares an input its command never references. |
undeclared-tool | A skill's command binary is not in the frontmatter tools list, so the manifest understates what the agent runs. |
Run it from a clone with bun run validate <file> (or agent3md validate <file>
with the Rust binary). It exits non-zero on any error, so it drops into CI.
Language-agnostic conformance vectors
The repo ships a labeled vector set in
examples/conformance/
so any loader or validator, in any language, can be checked against the same
fixtures. The contract: every valid-*.3md must pass with zero errors, and every
invalid-*.3md must be rejected by exactly the one rule it is named for (each
invalid file violates a single rule and is otherwise conforming).
Valid vectors
| File | Exercises |
|---|---|
valid-minimal.3md | The smallest conforming agent. |
valid-deps.3md | Skills with [[z=N]] dependency links. |
valid-cost.3md | Optional cost= tags and inputs=. |
valid-entry.3md | An entry: that resolves to a real plane. |
valid-fallback-identity.3md | No kind=identity: the first plane is the identity. |
valid-typed-inputs.3md | Typed inputs (name:type?) and a per-skill tool=. |
valid-command.3md | A command template whose placeholders match its inputs (and no model). |
Invalid vectors
| File | Rule it must fail |
|---|---|
invalid-two-identities.3md | identity |
invalid-missing-label.3md | missing-label |
invalid-dup-skill.3md | unique-skill |
invalid-dead-link.3md | dead-link |
invalid-cycle.3md | cycle |
invalid-missing-frontmatter.3md | frontmatter (a missing name) |
invalid-bad-entry.3md | entry |
invalid-bad-input-type.3md | input-type |
invalid-dup-input.3md | dup-input |
invalid-bad-placeholder.3md | tool-input |
Check a single vector with bun run src/validate.ts examples/conformance/<file>.
See also
- Skills and the format: the rules in context.
- Loaders: the contract every implementation must satisfy.