This document describes the reference architecture of the [&] Protocol and how its core artifacts fit together.
It is written for engineers who want to understand the protocol as a system, not just as a schema or a CLI.
The [&] Protocol defines the composition layer of the agent stack.
It is responsible for:
capability declaration
capability compatibility
capability contracts
governance as data
provenance requirements
downstream artifact generation
It is not responsible for replacing:
MCP tool invocation
A2A delegation semantics
UI rendering protocols
model inference runtimes
storage engines
deployment platforms
A concise framing is:
MCP defines how agents call tools. A2A defines how agents call agents. [&] defines how capabilities compose into a coherent agent.
A useful architecture view of the ecosystem is:
| Layer | Concern | Typical Protocols |
|---|---|---|
| UI | agent-to-user rendering | AG-UI, A2UI |
| Composition | capability declaration, validation, provenance, governance | [&] |
| Coordination | agent-to-agent delegation and discovery | A2A, ACP |
| Context | agent-to-tool connectivity | MCP |
| Runtime | execution, storage, orchestration, observability | framework-specific |
The protocol exists because there is currently no standard, machine-readable layer for declaring how an agent's cognitive capabilities fit together before runtime wiring begins.
The protocol has five primary architectural concepts (stable across the six-primitive vocabulary):
capability primitives
canonical declarations
contracts
registry artifacts
generated downstream configuration
These concepts are designed to remain valid across programming languages and runtimes.
The protocol starts with six primitive capability domains:
&memory
&reason
&time
&space
&body
&govern
The first four are cognitive building blocks; &body is the sensorimotor primitive (perception, action, affordance, state-encoding for replay); &govern is the cross-cutting operational primitive.
Examples of subtypes:
&memory.graph
&memory.vector
&memory.episodic
&reason.argument
&reason.vote
&reason.deliberate
&reason.attend
&time.anomaly
&time.forecast
&space.fleet
&space.route
&body.browser
&body.os
&govern.telemetry
&govern.escalation
&govern.identity
This gives the protocol a compact vocabulary for describing an agent's architecture.
The canonical artifact is ampersand.json.
This file declares:
agent identity
version
capabilities
provider bindings
provider config
governance constraints
provenance preference
This declaration is the source of truth for the rest of the architecture.
Capability contracts describe the typed operational behavior of a capability.
A contract can define:
supported operations
input types
output types
adjacency rules with accepts_from
adjacency rules with feeds_into
optional A2A skill mappings
Contracts make composition checkable instead of merely descriptive.
A registry publishes:
known primitives
known subtypes
known providers
provider support metadata
optional links to contracts
This is especially useful when a declaration uses provider: "auto".
A valid declaration can compile into downstream artifacts such as:
MCP configuration
A2A-style agent cards
This means the architecture is not just descriptive. It is executable.
The repository is structured around the protocol lifecycle.
README.md — protocol overview and quick start
SPEC.md — markdown protocol specification
schema/ — machine-readable schema artifacts
examples/ — validating example declarations
reference/ — reference implementation(s)
docs/ — conceptual and practical documentation
site/ — website/source publishing assets
tools/ — helper scripts
This layout is intentional.
A protocol repo should not be only:
prose docs
a website
or a reference implementation
It should contain all three layers:
specification
machine contracts
working implementation
That reduces ambiguity and helps keep the docs, schema, and code aligned.
The protocol currently uses a schema suite rather than one oversized schema.
ampersand.schema.jsonThis schema validates canonical agent declarations.
It defines the shape of:
$schema
agent
version
capabilities
governance
provenance
It is the primary entry point for validation.
capability-contract.schema.jsonThis schema validates capability contract artifacts.
It defines the structure of:
capability
operations
accepts_from
feeds_into
a2a_skills
This is the schema that makes typed composition portable.
registry.schema.jsonThis schema validates registry documents that publish:
primitive namespaces
subtypes
providers
protocol metadata
It supports capability discovery and provider resolution.
Using multiple schemas keeps the architecture modular.
Each artifact has a different role:
declarations describe an agent
contracts describe capability behavior
registries describe discovery and availability
Separating them avoids conflating concerns and makes implementations easier to reason about.
A declaration is a normalized description of an agent's capability architecture.
An ampersand.json declaration usually includes:
$schema
agent
version
capabilities
It may also include:
governance
provenance
There are two main binding modes.
A declaration directly names the provider.
Example idea:
&memory.graph → graphonomous
This mode is best when:
the runtime is already known
the provider is fixed
reproducibility matters more than discovery
A declaration uses provider: "auto" with a need.
This mode is best when:
provider resolution should happen later
discovery is dynamic
the declaration should preserve intent without locking a provider
Capabilities are stored as object keys rather than positional list items.
This design supports set-like semantics:
declaration order does not define meaning
duplicates collapse naturally
capability identity is explicit
This makes composition behavior easier to normalize and validate.
The protocol treats capability sets as algebraic structures.
A valid capability set should preserve:
commutativity
associativity
idempotence
identity
These properties are important because multiple tools or users may assemble the same declaration in different ways, and they should converge on the same result.
Set-like composition does not mean every merge is valid.
A conflict occurs when the same capability appears with incompatible bindings.
Example:
&memory.graph bound to graphonomous
&memory.graph bound to neo4j-memory
That is not an idempotent duplicate. It is a real conflict that should be surfaced explicitly.
Composition answers:
What capabilities does the agent contain?
Execution answers:
How does work flow through those capabilities?
Keeping those separate makes the protocol easier to validate and implement.
Pipelines represent data flowing through capability operations.
|>The pipeline operator is a conceptual notation used in this documentation to show ordered flow between capability operations.
It means:
one operation produces an output
the next operation accepts that output as input
Example shape:
stream_data
&time.anomaly.detect
&memory.graph.enrich
&reason.argument.evaluate
Unless a specific CLI, SDK, or runtime explicitly documents |> as supported input syntax, readers should treat it as pseudocode rather than canonical protocol grammar.
A runtime may represent the same pipeline in other forms, such as:
a validated sequence in a declaration
a contract-aware internal execution plan
a generated MCP or A2A artifact
an execution DAG or other runtime-specific graph
A pipeline is valid only if:
each capability exists
each operation exists
output and input types align
feeds_into allows the transition
accepts_from allows the transition
Before execution begins, a conforming runtime should be able to check these conditions and either:
accept the pipeline and materialize an execution plan
reject the pipeline with a precise compatibility error
This architecture prevents pipelines from being treated as informal glue.
The protocol moves pipeline safety earlier in the lifecycle.
Instead of waiting for runtime failures, implementations can reject invalid compositions before deployment or generation.
That means the protocol separates two moments clearly:
composition-time checks validate structure, contracts, and allowed transitions
runtime execution invokes providers, enforces governance, and emits provenance for each realized step
Governance is expressed as portable data.
The governance object can contain:
hard
soft
escalate_when
infer_from_goal
If governance only exists in runtime code, then:
it is hard to audit
it is not portable
it becomes implementation-specific
it cannot travel with the declaration
By expressing governance in the declaration, the protocol lets implementations preserve the same safety intent across languages and runtimes.
The protocol defines the structure of governance.
A runtime still decides:
how hard constraints are enforced
how soft constraints are used in reasoning
how escalation is implemented operationally
So the architecture separates:
governance declaration
from
governance execution
That is an intentional boundary.
Provenance is a required architectural concept for trustworthy composition.
A provenance record may include:
source capability
provider
operation
timestamp
input hash
output hash
parent hash
optional runtime trace IDs
A hash-linked provenance chain allows the system to answer questions like:
why was this decision made
which capability produced this context
what output depended on what input
what runtime call corresponds to this step
This is especially important for:
audits
debugging
regulated workflows
governance review
trust and explainability
Provenance is not just logging.
It is a protocol-level requirement that says:
composed cognition should preserve lineage
That makes provenance part of the architecture contract rather than an optional afterthought.
The protocol makes a strict distinction between capabilities and providers.
Examples:
&memory.graph
&time.anomaly
&reason.argument
These are protocol concepts.
Examples used throughout this documentation include:
graphonomous
ticktickclock
deliberatic
geofleetic
Unless a registry entry, repository artifact, or implementation guide says otherwise, these names should be read as illustrative provider examples rather than guaranteed public implementations.
What matters at the protocol level is the role they play:
a capability such as &memory.graph is the interface
a provider such as graphonomous is one possible implementation of that interface
If capabilities and providers are collapsed into one concept, then:
interoperability disappears
schemas become vendor-specific
portability suffers
composition becomes branding instead of protocol design
The architecture is stronger when capabilities remain vendor-neutral.
The registry is the discovery and resolution layer.
A registry can publish:
primitive roots
subtype definitions
operation metadata
provider availability
transport/protocol identifiers
contract references
The registry supports:
provider: "auto"
compatibility discovery
provider lookup
downstream generation
capability publishing
The protocol does not require one global registry service implementation.
It only requires a machine-readable registry model.
That means different ecosystems can host their own registries while preserving the same artifact shape.
One of the most important architectural goals of the protocol is that a declaration should compile into downstream artifacts.
MCP generation turns a validated declaration into a tool-facing configuration.
That may involve:
grouping capabilities by provider
resolving provider launch details
creating stdio or URL-based config entries
preserving unresolved providers explicitly
The generator should not invent details that are not grounded in known provider information.
A2A generation turns a validated declaration into an agent-facing coordination artifact.
That may include:
agent identity
skill list
provider bindings
governance metadata
provenance metadata
This shows that the same declaration can support both runtime integration and coordination publication.
This is what makes the protocol more than documentation.
A declaration is not just read by humans. It is transformed into real operational artifacts.
The Elixir reference implementation is intentionally small and layered.
Its main modules correspond to the protocol architecture:
schema validation
composition
contract checking
MCP generation
A2A generation
CLI entrypoint
The purpose of the reference implementation is to prove:
the schema is usable
composition is checkable
generation is possible
the protocol can be grounded in real code
It is not intended to be the only runtime or the final production architecture.
A protocol spreads through interfaces that developers can actually use.
The CLI acts as the operator surface for the lifecycle:
validate
compose
generate
This makes the architecture easier to adopt and test.
The documentation should mirror the system architecture.
A healthy documentation hub should include:
overview
formal spec
positioning
FAQ
architecture guide
capability deep dives
reference examples
This structure matters because different audiences need different entry points:
engineers want artifacts and implementation detail
researchers want conceptual framing
adopters want examples and workflows
contributors want repository conventions
The full architecture flow looks like this:
author an ampersand.json
validate it against the canonical schema
normalize the capability set
optionally check capability contracts and pipeline compatibility
preserve governance and provenance semantics
resolve providers directly or through a registry
generate downstream artifacts such as MCP config and A2A agent cards
This can be summarized as:
declaration → validation → composition → resolution → generation
That is the central execution model of the protocol.
Consider a small operations agent with these declared capabilities:
&time.anomaly bound to ticktickclock
&memory.graph bound to graphonomous
&reason.argument bound to deliberatic
Assume the intended flow is:
detect an anomaly
enrich it with graph memory
evaluate candidate actions with argument-based reasoning
A conforming runtime processes that declaration in stages rather than all at once.
validateThe validation step should answer:
is the declaration structurally valid
are required fields present
are capability identifiers known
are governance and provenance blocks well-formed
A typical CLI interaction might look like:
$ ampersand validate ampersand.json ✔ schema valid ✔ capabilities normalized: 3 ✔ governance block valid ✔ provenance mode accepted: hash_chain
At this stage, the runtime has not executed providers yet. It has only established that the declaration is well-formed enough to continue.
composeThe composition step should answer:
do the declared capabilities coexist without conflict
do requested operations exist on their contracts
do adjacent steps agree on input and output types
are accepts_from and feeds_into constraints satisfied
A typical CLI interaction might look like:
$ ampersand compose ampersand.json ✔ provider bindings resolved ✔ contract check passed for
&time.anomaly.detect✔ contract check passed for&memory.graph.enrich✔ contract check passed for&reason.argument.evaluate✔ execution plan created: detect → enrich → evaluate
This is the stage where a runtime turns a declaration into an executable plan. If a provider is still unresolved because the declaration uses provider: "auto", the runtime should preserve that unresolved state explicitly rather than inventing a binding.
Once validation and composition succeed, runtime execution can begin.
A typical execution loop is:
invoke the first provider operation
capture its typed output
verify the next step can accept that output
attach provenance for the completed step
apply governance checks before, during, or after the step as required
continue until the pipeline or task completes
For the example above, that means:
ticktickclock emits an anomaly event
graphonomous enriches that event with related incidents or topology context
deliberatic evaluates candidate responses under the declared governance rules
This is the practical bridge between declaration and behavior.
generateGeneration turns the composed plan into downstream artifacts.
A typical CLI interaction might look like:
$ ampersand generate --target mcp ampersand.json ✔ wrote MCP configuration for 3 provider bindings $ ampersand generate --target a2a ampersand.json ✔ wrote A2A agent card with 3 exposed skills
The exact artifact shape depends on the target, but the important point is that generation happens after validation and composition, not instead of them.
If a pipeline step is incompatible, the runtime should fail before generation or execution.
For example, if one step emits anomaly_event but the next step requires forecast_window, a conforming implementation should surface a targeted error such as:
$ ampersand compose ampersand.json ✖ pipeline invalid at step 2 output
anomaly_eventdoes not satisfy required inputforecast_windowtransition not allowed by declared capability contracts
This is what makes the protocol operational rather than merely descriptive: a runtime can explain not only what an agent declares, but why a composition is accepted or rejected.
Consider an incident response or infrastructure operations agent.
Its declaration may include:
&memory.graph
&time.anomaly
&space.fleet
&reason.argument
Architecturally, that means:
memory stores and recalls similar incidents
time detects anomalous behavior
space localizes impact across regions or fleets
reason evaluates possible actions under governance constraints
The protocol gives that architecture a portable machine-readable representation.
Without the protocol, those pieces often exist only as implicit framework wiring or prompt conventions.
This architecture is intentionally narrow in a few places.
It does not try to standardize:
all runtime execution semantics
all transport protocols
all memory implementations
all reasoning models
all deployment and orchestration
all UI behavior
Its focus is the composition layer.
That narrowness is a strength. It keeps the protocol understandable and implementable.
When extending the protocol, preserve these architectural principles:
If a new concept matters, it should be represented in schema and examples, not only prose.
Keep capability identity separate from provider identity.
If provider launch or integration details are unknown, leave them unresolved explicitly.
Keep constraints portable and machine-readable.
Do not bolt lineage on later.
Prefer a compact, extensible primitive vocabulary over an explosion of top-level categories.
If you are trying to understand the architecture for the first time, read the repository in this order:
README.md
SPEC.md
protocol/schema/v0.1.0/ampersand.schema.json
protocol/schema/v0.1.0/capability-contract.schema.json
protocol/schema/v0.1.0/registry.schema.json
examples/
reference/elixir/ampersand_core/
docs/positioning.md
docs/comparison-table.md
That moves from concept to contract to implementation.
The [&] Protocol architecture is built around one central idea:
an agent should have a portable, machine-readable declaration of how its cognitive capabilities compose before runtime integration is generated
To make that possible, the architecture includes:
a canonical declaration format
a schema suite
capability contracts
a registry model
governance as data
provenance requirements
generators for MCP and A2A
a reference implementation and CLI
That is the composition layer this protocol is designed to provide.