Portable agent format
bnw.agent-manifest/1 is the first Milestone 9 application profile. It describes a portable agent without binding that agent to one machine, model provider, tool server, or centralized scheduler.
The manifest is an immutable descriptor carried by an ordinary agent.portable capability manifest. The outer BNW capability identifies the publisher and logical subject. The descriptor references immutable instructions and exact stable capabilities required to run the agent.
Version 1 contract
Section titled “Version 1 contract”An agent manifest contains:
- a display name and optional description;
- one immutable instructions content ID;
- 1–64 required roles, each bound to one exact capability ID;
- up to 32 immutable policy content IDs;
- an optional exact memory capability ID; and
- the fixed
agent/runinput/output contract.
Requirement roles are machine-safe local names such as model, search, or finance-data. Roles must be unique. Version 1 uses exact capability IDs deliberately: fuzzy constraints, pricing, ranking, and automatic substitutions require explicit later resolution semantics.
Instructions and policies are references, not embedded authority. Their content, confidentiality, availability, and interpretation remain application concerns. A capability reference identifies a signed stable definition; a later resolver must still find acceptable active provider offers and apply local trust and authorization policy.
Create and publish
Section titled “Create and publish”First store the instructions and any policy documents as immutable BNW blobs. Record the printed blob IDs:
bnw blob put agent-instructions.md --media-type text/markdownbnw blob put agent-policy.json --media-type application/jsonCreate the portable manifest. Repeat --require for every exact dependency and --policy for every policy object:
bnw capability descriptor create-agent portable-agent.json \ --name "Portable research agent" \ --description "Researches a topic using fixed model and search capabilities" \ --instructions <INSTRUCTIONS_BLOB_ID> \ --require model=<INFERENCE_CAPABILITY_ID> \ --require search=<SEARCH_CAPABILITY_ID> \ --policy <POLICY_BLOB_ID> \ --memory <MEMORY_CAPABILITY_ID>The command sorts requirements and policies into their deterministic representation, validates every identifier and bound, stores the descriptor locally, and prints its content ID.
Validate, inspect, and publish it:
bnw capability descriptor validate portable-agent.jsonbnw capability descriptor inspect <AGENT_DESCRIPTOR_ID>bnw capability publish agent.portable <AGENT_DESCRIPTOR_ID>Another peer can discover and follow the agent through the existing bounded capability path:
bnw capability discover agent.portablebnw capability list --kind agent.portablebnw capability inspect <AGENT_CAPABILITY_ID>bnw capability follow <AGENT_CAPABILITY_ID>Publishing an agent manifest does not execute it, grant access to its dependencies, or endorse their providers. Version 1 establishes the immutable portable definition. Local resolution checks each exact requirement against canonical manifests and active provider offers while retaining missing and policy-rejected outcomes rather than hiding them behind a global scheduler.
Resolve dependencies
Section titled “Resolve dependencies”After following and synchronizing every referenced capability, resolve the agent locally:
bnw agent resolve <AGENT_CAPABILITY_ID>The resolver validates each exact capability and descriptor, ignores expired and zero-slot offers, collapses offer renewals by provider, and selects a stable local candidate. Economic constraints are optional:
bnw agent resolve <AGENT_CAPABILITY_ID> \ --credit-issuer <ISSUER_BNW_ID> \ --max-per-invocation-micros 5000000Prices are compared only within one issuer’s service-credit system. See ECONOMICS.md. Resolution does not invoke dependencies, reserve credits, or grant authority.
In the web client
Section titled “In the web client”Capabilities → Provide a capability → Agent publishes a manifest: name, description, instructions, and requirements by role, each picked from the catalog. The node stores the instructions as a blob, sorts the requirements by role, and publishes the capability, as capability descriptor create-agent and capability publish agent.portable do. The form warns when no inference.model requirement is present.
The requirement picker filters the catalog by kind on the node and by name in the browser, and can load more pages.
Policies, memory, and the run contract, a collapsed section of the form, covers what the CLI flags do:
- Policies. Texts separated by a line holding only
---, at most 8 from the web client. Each becomes an immutable blob, and the manifest lists their content IDs, sorted. - Memory. An exact memory capability.
- The
agent/runcontract. Media types, size limits, privacy, and optional JSON Schemas.
Published agents appear under My capabilities. They need no offer or backend, because they run on whichever node adopts them.
An agent.portable capability’s page shows the instructions, fetching them from peers when missing. The publisher’s node, and every node that follows the agent, serves its instructions and policies, so they can be fetched while the publisher is offline. It also shows each requirement with the provider and terms the resolver would choose, or the reason there is none.
Publish an agent you host
Section titled “Publish an agent you host”An agent hosted on your node can be published as a portable agent from its page: Publish as portable agent opens the Agent form, filled in from how the agent runs now. The form includes its name, its instructions (or the built-in ones), its model as the model requirement, and each tool its operators let it use as tool-1, tool-2, and so on. Review it, then publish.
- Signing. The node signs the manifest as its publisher and names the hosted agent as its subject, so the catalog shows which agent it describes. The agent’s own key first delegates
capability:publishto the node for a year, renewed on a later publish when less than a month remains. Other nodes verify that delegation before they show the node’s authority over the agent. - Access. Publishing grants nothing. Whoever runs the agent needs their own access to its model and tools.
- Instructions. They become a blob anyone who finds the agent can fetch, so keep secrets out of them.
Run on this node
Section titled “Run on this node”Run this agent here (or bnw agent runtime --from-manifest <AGENT_CAPABILITY_ID> [--enable]) configures the node’s agent runtime from the manifest:
- the instructions;
- its
inference.modelrequirement as the model (preferring the rolemodel); - the resolved provider of that model.
It is refused in these cases, with the reason shown:
- the instructions are not local yet;
- they exceed the runtime’s 8 KiB limit;
- there is no model requirement;
- the model has no offer;
- the only offer belongs to the node’s own identity, which cannot invoke itself.
Other requirements are tools. The agent’s operators still decide which of them it may use, through agent:invoke grants.
