Skip to content

Terraform is for infrastructure. Docker is for services. Sigma is for detection.

.vio is for agents.

VIO — Verifiable Intelligence Object. The signed artifact format for AI agents.

The .vio artifact format is open, signed and framework-neutral. One YAML document carries what an agent knows, does and remembers — and the signatures that prove who authored it.

Format versionvio: 1
SpecificationVIO 1.0 · Accepted · rev 5 · 2026-09-22
Artifact types5 (prompt · skill · memory · model · agent)
Tooling required to read oneNone — portable YAML core only
IntegrityDigest-verified · RFC 8785 · signing reserved for vio: 2
LicenceCC-BY-4.0 spec · Apache-2.0 tooling · patents royalty-free

Other agent formats describe an agent. .vio packages, pins and signs one.

A Dockerfile pins a filesystem. A Helm chart pins a topology. An agent-definition schema pins a description. None of them produces a portable artifact whose every part is digest-pinned and whose authored parts are signed — which is what you actually hand to a deployer.

Previous layer

Dockerfile · Helm · Terraform

Built for processes, files and cloud resources. They describe the box, not the behavior inside it. An agent's prompt, skills, tools and memory are opaque payload.

New surface

Agent composition

Prompts, skills, tools and connector scopes, memory, model descriptors, decode parameters — the artifacts that decide what an agent knows, does and remembers. This is where drift, tampering and privilege creep actually happen.

The format

.vio

A single self-contained, signed YAML bundle. Every authored artifact is individually signed; every referenced one is digest-pinned; one bundle signature binds them all. Framework-neutral. Readable by any YAML parser. Forward-compatible by construction.

Before OCI in 2015, every runtime had its own image format. Before Terraform, every team had its own provisioning scripts. Agent definitions sit in the same position today: every framework ships its own YAML, none of it signed, none of it portable. .vio is the artifact layer that position is missing.


Three concerns stack. None reinvents the others.

The format sits between a signing substrate it depends on and a deployer that consumes it. It defines packaging only — not cryptography, not scheduling.

Sign
How an artifact, or a whole bundle, is signed, verified and trust-scored. Signing ceremony, key registry, verification engine, enforcement gate. Provided by Viorant Sign. Signing is optional — an unsigned bundle is a valid bundle; when signatures are present, the format defines only how Sign's outputs are represented in the file.
.vio
How signed artifacts are packaged together. Manifest, artifact bodies or references, digests, per-artifact signatures and the bundle signature. This site.
Deployer
Verifies the bundle via Sign, then deploys. Resolves references on the target, routes each artifact by its declared deploy destination, binds runtime values after verification. Reference implementation: Helix.


Capability is signed. Credentials are not.

The signed content of a skill includes its tool declarations — connector and scopes. You cannot add a tool or widen a scope without breaking the signature. But OAuth tokens, secret values and bound variables never enter the file: they are injected at run, after verification, through connection:// and secret:// handles.

The consequence is a property no container format has: a tamper-evident, auditable capability surface that travels with the artifact, while permission-to-act-here is resolved per deployment.

The same reasoning makes templates the signed unit rather than rendered strings. Verification happens on the template; interpolation and framework assembly happen afterwards. One signed prompt serves every run, and every injected value is bound to a verified template.

How signing is represented
# skill artifact — inside the signature
tools:
  - { ref: http_get,   kind: viorant }
  - { ref: serp_query, kind: mcp,
      connector: serpapi, scopes: [search.read] }

# manifest — surfaced so the deployer can gate auth
requires:
  - { connector: serpapi, scopes: [search.read], auth: oauth }

# prompt variables — the schema is signed, the values are not
variables:
  - { name: client, type: string, required: true, source: input }
  - { name: key,    type: string, required: true, source: secret }
bindings:
  client: input.client
  key:    secret://viorant/rnd/serp_key   # resolved at run

A complete bundle, in one document.

A research agent bundling a signed prompt, one declarative and one executable skill, a memory reference and a self-hosted model reference. Open it in any YAML tool.

vio: 1
manifest:
  id: summarizer
  name: Summarizer
  composition: agent
  framework: crewai
  created: '2026-09-15T00:00:00.000Z'
  artifacts:
    - id: summarizer-prompt
      deploy: registry
      digest: sha256:60bc98762dc2aa438fb3cc1ddc6a44e11c1866ebe56860d355286f70ba32abe6
      type: prompt
    - id: summarizer
      deploy: runtime
      digest: sha256:16a546abb7772d65296296dcd1636780ca8f677f71afffa6d109d91ec926743b
      type: agent
  requires:
    - connector: openai
      scopes: []
      auth: api_key
      kind: model
      tools: []
artifacts:
  - id: summarizer-prompt
    type: prompt
    mode: single_shot
    content:
      system: You are a concise assistant. Summarize the text you are given in exactly three bullet points. Do not add anything that is not in the text.
      user: |-
        Summarize this:

        {{text}}
    variables:
      - name: text
        type: string
        required: true
        source: input
        description: The text to summarize.
  - id: summarizer
    type: agent
    content:
      role: Summarizer
      goal: Turn any text into a three-bullet summary.
      framework: crewai
      model:
        ref: provider://openai/gpt-4o-mini
      prompts:
        - ref: summarizer-prompt
      skills: []
      inputs:
        - name: text
          type: string
          required: true
          description: The text to summarize.

Self-describing

The agent references siblings by local id. No external lookup is needed to understand the composition; the deployer wires them at deploy.

Routing is declared, not inferred

Each artifact carries its own deploy destination — runtime, standalone sidecar, registry or store. A deployer reads it; it never guesses.

Forward-compatible

Unknown type, framework, deploy or kind values are reserved. A verifier that does not understand one rejects cleanly rather than mis-deploying.


The standard is one thing. What is built is another.

The specification is written at its target altitude: all five artifact types, multiple frameworks, org and team scope. The reference implementation exercises a deliberate subset of it. The line between the two is published, dated and maintained — a format earns trust by saying what it does not yet do.

Implemented subset
Manifest, artifact index, embedded prompt / skill / agent bodiesshipped
Templated artifacts — sections, variables, bindings, two-facet outputshipped
Memory bodies with layer (seed / runtime)shipped
Models rail and connector rail resolved at runshipped
CrewAI adaptershipped
Per-artifact sig and the vio_bundle signaturespecified
Off-machine deploy — gates and destinationsspecified
LangChain, AutoGen, ACP adaptersplanned
Multi-agent composition: bundleopen

Read a bundle with the parser you already have.

A .vio uses only the portable YAML core: block scalars for bodies, plain maps and sequences. No anchors, no custom tags, no merge keys. Any parser opens it; any formatter lints it.

# python import yaml b = yaml.safe_load(open("minimal_prompt.vio")) print(b["vio"], b["manifest"]["id"]) for a in b["manifest"]["artifacts"]: print(a["id"], a["type"], a["deploy"]) # → 1 summarizer # → summarizer-prompt prompt registry # → summarizer agent runtime

Verification runs over the canonical form, not the on-disk bytes, so cosmetic reformatting — key order, quoting, indentation — is signature-safe. The one exception is a formatter that rewrites a block scalar: that changes the body string, the digest and the signature, which is tamper detection working as designed.

A dedicated .vio parser — typed access to the manifest, index and bodies, with canonicalization built in — is coming; it is a convenience, never a requirement.

AcceptedFormat version 1VIO 1.0 · Revision 5 · 2026-09-22Canonical: /specVerifiable Intelligence ObjectPatent pending

The .vio Artifact Specification

The VIO Project · Authors: Vivien Roggero, Adi Vora — Viorant Inc.

The portable, signed deployment artifact for AI agents. A .vio is what gets handed from "the engineer composed this agent" to "this agent is running somewhere."

History. An earlier draft defined .vio as an OCI image carrying an org.viorant.manifest.v1 annotation. That model is retired. A .vio is a single self-contained, signed YAML bundle; OCI images are relocated to the deployer's pre-baked base images, which are not the .vio itself. The "pull and run any .vio as a container" property no longer holds. See Errata.

What a .vio is#

A .vio is a single self-contained, signed bundle of AI-infrastructure artifacts. It is the unit a conforming deployer consumes. One file carries everything needed to verify provenance and deploy: a manifest, the artifact bodies (or references to them), and the signatures that bind them.

Three concerns stack — none reinvents the others:

Sign      = how an artifact (or a whole bundle) is signed, verified, trust-scored   → dependency
.vio      = how signed artifacts are packaged together                              → this document
Deployer  = verifies the .vio via Sign, then deploys                                → Deployer specification

Signing is optional; its representation is not. An unsigned bundle is a valid bundle and is what a local compile-and-run produces. When a bundle is signed, the signing ceremony, key registry, verification engine, trust scoring and enforcement gate are defined by Viorant Sign (sign.viorant.ai, coming soon). This document only defines how Sign's outputs are represented inside a .vio; it does not re-specify cryptography. Sign treats vio_bundle as a first-class signable asset type with a defined canonicalize_vio_bundle() (RFC 8785 canonicalization); the format below is built to match.

This specification is written at its target altitude — all five artifact types, multiple frameworks, org and team scope — not narrowed to today's implemented subset. Section 3 states exactly which parts the current reference implementation exercises.

1. Physical format#

  • Encoding. A single UTF-8 YAML document. Chosen over JSON because every artifact body is multi-line text — prompts, skills, memory, agent definitions — and YAML block scalars keep them verbatim and diff-able instead of base64 or escaped one-liners. Chosen over an archive because .vio is a first-class format, not a renamed container.
  • Top-level keys. vio (format-version integer), manifest (authoritative metadata, signed as a unit), artifacts (the bodies).
  • Plain-YAML guarantee. A .vio uses only the portable YAML core — UTF-8, block scalars for bodies, base64 (ASCII) for signatures, plain scalars, maps and sequences. No anchors or aliases, no custom !tags, no merge keys (<<), no binary framing. Any YAML parser or formatter can open and lint a .vio with no format-specific tooling.
  • Formatting versus the signature. Verification runs over the canonical form (canonicalize_vio_bundle, RFC 8785), not the on-disk bytes, so cosmetic reformatting — key order, flow versus block style, quoting, indentation — is signature-safe. The one exception: a formatter that rewrites a block scalar (| to |-, trailing newline, internal whitespace) changes that artifact's body string, therefore its digest, therefore its sig. That is tamper detection working as designed. Read and lint with any tool freely; only an authoring or save path must preserve block scalars exactly (use a canonical writer) or re-sign.

1.1 The embed-versus-reference rule#

A single text document cannot hold model weights or multi-file code. So:

CaseRepresentation
Text, small — prompt, declarative skill, single-file Python or JS skill, agent definition, memory bodyEmbedded inline as a YAML block scalar (content: |)
Heavy or non-text — models, always; multi-file or dependency-bearing executable skillsReferenced by ref and pinned by digest (git ref, OCI image, model://…)

The deployer resolves a ref on the target at deploy time; the manifest digest guarantees the resolved bytes are the ones that were signed for.

1.2 Manifest field reference#

FieldMeaning
id, name, versionPackage identity (semver)
compositionagent | prompt | skill | memory | model | bundle
frameworkFor agents: crewai | langchain | autogen | … (null otherwise)
org, teamScope — drives trust, RBAC and registry namespace
signer{ certificate_id, algo_id } — resolves in Sign's public_keys registry
createdISO-8601 UTC
artifacts[]Authoritative index — each: id, type, kind?, runtime?, deploy, digest, sig?, ref?
requires[]Cross-artifact dependencies (agent → model {id, digest}, connector dependencies)

1.3 Artifact index entry#

Each row in manifest.artifacts[] is the authoritative descriptor for one artifact:

KeyMeaning
idBundle-local id, referenced by siblings — e.g. an agent's prompts: [{ref: sysprompt}]
typeprompt | skill | memory | model | agent
kindFor skill: declarative | executable (extensible per type)
runtimeFor executable skill: python | js
deployDestination and mode: runtime | runtime/standalone | registry | store
digestsha256:… of the content bytes — binds the artifact into the signed manifest
sigPresent only on authored artifacts (§2) — absent for digest-only references
refPresent only for referenced artifacts (model, external skill)

1.4 Worked example#

A CrewAI research agent bundling a signed prompt, one declarative and one executable skill, a memory reference and a self-hosted model reference. The full document is on the front page; the shape is reproduced in the reader.

Three properties of this design:

  1. Self-describing. The agent body references siblings by local id; the deployer wires them at deploy. No external lookup is needed to understand composition.
  2. Per-artifact deploy. Routing is declared, not inferred — the deployer reads deploy and sends each artifact to Runtime, Registry or Store.
  3. Forward-compatible. Unknown type / framework / deploy / kind values are reserved — a verifier that does not understand a value rejects cleanly rather than mis-deploying. Unknown keys, by contrast, are also rejected — so adding a field costs a format version. The format does not grow without breaking older readers.

1.5 Templated artifacts — sections, variables, binding#

An authored artifact is a template, not a finished string. A prompt's content is a map of framework-neutral sections; the .vio stays framework-neutral and a framework adapter assembles the native form at instantiate — the same principle as {{var}}.

Prompt artifact shape

FieldMeaning
modechat | single_shot — tells the adapter whether to build a message array or one completion
content.systemSystem prompt (template with {{vars}})
content.userUser prompt (template with {{vars}})
variables[]The dynamic-slot schema (below); spans all sections
bindingsArtifact-level defaults — the prompt is self-runnable from a registry

Output is an agent field, two-faceted — not a prompt field. A prompt is reusable across agents with different expected outputs, so the output contract lives on the agent. output.expected is prose; it shapes the prompt, so the adapter folds it into assembly like a section. output.schema is an optional typed (JSON-schema) contract the runtime uses to validate or coerce the result and to wire source: task between agents in a crew.

Variable schema

variables:
  - { name: client, type: string, required: true,  source: input }
  - { name: today,  type: date,   required: false, source: env,    default: "now()" }
  - { name: tier,   type: enum,   values: [fast, deep], default: deep, source: static }

source ∈ input | env | task | connector | secret | static:

  • input — supplied by the caller at each run (kept dynamic)
  • env / task / connector — resolved by the system: deploy environment, upstream task output, tool result
  • secret — a secret://org/team/key reference, resolved at run from a secret store; the value never enters the .vio
  • static — baked at compose time (effectively fixed)

Binding — the explicit "what stays dynamic" — maps each variable to its source. Bindings sit at the artifact level (so a lone prompt runs on its own) and an agent may override them when it composes the prompt. The override is recorded in the agent's signed content, leaving the prompt's signature intact. The agent aggregates unbound input variables into its inputs contract; a run that omits a required input fails validation before execution.

Why templates, not finished strings. Values bind at runtime, outside the signature — so one signed template serves every run without re-signing, and injected values are still bound to a verified template (§2.4).

1.6 Skills and tools#

A skill is a file tree, not one file. Skills are directories — SKILL.md plus scripts/, references/ and assets. The tree is represented as a files map keyed by relative path, plus an entry pointer; the manifest index entry carries entry and the one digest over the canonicalized tree:

# manifest index entry
- { id: research, type: skill, kind: executable, runtime: python,
    entry: scripts/run.py, deploy: runtime/standalone, digest: sha256:…, sig: base64… }

# artifacts body
- id: research
  type: skill
  entry: scripts/run.py
  files:
    SKILL.md:                  | …     # how and when to use
    scripts/run.py:            | …     # entrypoint
    scripts/helpers.py:        | …
    references/methodology.md: | …
  tools: [ … ]
  • The tree is the signed unit. digest is sha256 over the canonicalized file map (sorted paths, per-file NFC) — exactly Sign's canonicalize_skill. Renaming a path or editing any file breaks the signature; paths are part of the signed structure, not just contents.
  • Embed-versus-reference still applies. Small text tree → inline files; heavy or binary tree (vendored dependencies, large assets) → ref plus digest (packed archive or OCI image), like models.
  • Single-file skills keep the content: | shorthand (a one-file tree); files is the general form. The same entry/files model applies to declarative skills (just SKILL.md).

A skill also declares the tools it uses. Tools come in two kinds:

kindSourceAuth
viorantNative capability provided by the runtime or base imageNone, or platform-internal
mcpA tool exposed by an MCP connector (Gmail, Slack, SerpAPI, …)OAuth, resolved per deployment on the control plane

Tool declaration on the skill artifact pins the exact tool and, for MCP, the connector and scopes — least privilege:

tools:
  - { ref: http_get,   kind: viorant }
  - { ref: serp_query, kind: mcp, connector: serpapi, scopes: [search.read] }

Connectors are control-plane references, never packaged in the .vio. A connector is org- or team-specific, OAuth-bound infrastructure — not a portable, signable artifact. The bundle surfaces its connector dependencies at the manifest level so a deployer can gate and resolve auth without parsing every skill body:

manifest:
  requires:
    - { connector: serpapi, scopes: [search.read], auth: oauth }

Capability is signed; credentials are not. The skill's signed content includes its tools declaration (connector and scopes), so a signed skill has a tamper-proof, auditable capability surface — you cannot add a tool or widen a scope without breaking the signature. OAuth tokens never enter the .vio: they live in the control-plane connector store and are injected to the runtime at run via a connection://org/team/connector handle (the same shape as the secret:// variable source; source: connector covers tool-result values).

Why OAuth "again". Tokens are per-org, short-lived and non-portable. Deploying a signed skill to a new org, team or cloud means that deployment's control plane must hold a valid connection for each required connector — so OAuth is (re-)done there if absent. Capability travels in the file; permission-to-act-here is resolved per deployment.

1.7 Models and inference#

The model type covers local, self-hosted models only. A model artifact is a reference plus an inference descriptor — never weights. The .vio carries a model://… ref (digest-pinned) plus the descriptor a deployer needs to stand it up, on the manifest index entry so it is covered directly by the bundle signature; the model itself stays body-less.

Field (manifest entry)Meaning
refmodel://org/name — the weights, resolved on the target at deploy
digestsha256 of the resolved weights (integrity, no authorship)
engineInference runtime: vllm | llama.cpp | ollama | … — selects the inference base image flavor
quantizatione.g. q4_k_m (optional)
context_lengthServed context window (optional)
served_asThe name the agent or framework calls (optional; defaults to name)
- { id: llama, type: model, deploy: runtime, ref: "model://viorant/llama3-8b",
    engine: vllm, quantization: q4_k_m, context_length: 8192, served_as: llama3-8b,
    digest: "sha256:7c33…" }   # no sig — integrity-only tier
  • Integrity-only, descriptor included. A model carries no sig — you cannot author-sign someone's weights — but the descriptor sits in the signed manifest and the digest covers the resolved weights. Both how it is stood up and what bytes run are tamper-evident (§2.3).
  • Hosted models are connectors, not model artifacts. A hosted LLM is not a type: model. type: model means self-hosted weights you deploy; a hosted model is an API credential you resolve, so it rides the connector rail — a control-plane connection, key injected at run via connection://, exactly like SerpAPI. The two trust and deploy profiles (deploy a container versus resolve a credential) stay cleanly separated.

Decode parameters are agent-level — not model- or prompt-level. How to stand the model up is the model's concern; how to sample it is how the agent uses it. Decode params (temperature, max_tokens, top_p, stop, …) layer like bindings:

# agent body
model:
  ref: llama
  params: { temperature: 0.2, max_tokens: 1500 }   # agent override

Precedence is run > agent > model-default: a model may publish recommended params on its manifest entry, the agent overrides, and a run may override per invocation. Params are config, not secrets — they live in the file as part of the agent's signed content. A prompt stays sampling-neutral, so params are never prompt-level.

1.8 Memory bodies and the layer field#

A memory artifact ships its .memory.md text inline as a body. A workspace holds two structurally identical kinds of memory — a curated seed the user authored, and an agent's local runtime scratch written by a remember tool — so the body declares which it is:

Field (artifact body)Meaning
layerseed | runtime — which memory layer this body is. Optional; defaults to seed.
artifacts:
  - id: 01M1NC0WFNSS0WWN1690VY2FR8
    type: memory
    layer: seed                       # curated — ships with its body text intact
    content: |
      ---
      meta: {id: 01M1NC0WFNSS0WWN1690VY2FR8, schemaVersion: "1"}
      name: Memory 1
      description: Persistent memory for agent runs.
      ---
      Viorant is an AI infrastructure company…
  - id: 01KYRN79YYQ841RD37EKSMGKK9
    type: memory
    layer: runtime                    # agent-local scratch — frontmatter only, body empty
    content: |
      ---
      meta: {id: 01KYRN79YYQ841RD37EKSMGKK9, schemaVersion: "1"}
      name: confluence-updates
      description: Persistent memory for agent runs.
      ---
  • Omitted means seed. A pre-layer bundle parses unchanged and is read as curated content — which is what those bundles actually carried. This is the safe default direction.
  • It lives on the body, not the manifest index entry. The body is where the deployer and runner read from; widening the index too would double the compatibility surface for no consumer.
  • It is not part of the digest subject. A memory artifact digests { content } only, so adding or changing layer leaves every existing manifest.artifacts[].digest valid — no forced re-export, no digest_mismatch on already-deployed bundles.
  • Materialization is layer-driven. A deployer writes seed → {id}.memory.md at the memory root and runtime → .runtime/{id}.memory.md, so the instance classifies each memory correctly on its first run rather than only after its first write.
  • A runtime body ships frontmatter-only, but it still ships. The producer emits the parsed frontmatter with an empty body: the agent's accumulated local history stays local, while the ULID binding survives. Omitting the artifact entirely is not an equivalent optimization — an absent write target fails the first run with a dangling reference.
  • A redeploy never clobbers accumulated runtime state. The deploy target checks for an existing runtime object before writing and skips it, emitting a preservation notice instead.
  • Compatibility runs consumers-first. The memory body schema is strict and the runtime parses the whole bundle at boot, so a bundle carrying layer is rejected by a runtime built against a pre-layer schema. Producers must ship after consumers — the reverse of the usual order.

Why the layer is declared rather than derived. An earlier design keyed this off the agent's memory.read / memory.write binding. That is the wrong axis: layer is a property of the asset (curated versus scratch), while binding is a property of the agent's reference to it — and a seed-layer memory can legitimately be write-bound, in which case the runtime promotes a copy into the runtime layer on first write rather than mutating the seed. .vio is a published portable format; an artifact should say what it is, rather than leaving the semantic implicit in a cross-reference every third-party consumer has to know to perform.

2. How signing is represented in a .vio#

The full cryptography belongs to Sign; this section defines only what appears in the file.

2.1 Two-tier trust#

You sign what you author; you digest-pin what you reference or what is mutable.

ArtifactTrust tierIn the file
promptSignedsig present; is a Sign prompt asset
skillSignedsig present; Sign skill asset (declarative and executable)
agentSignedsig present; the bundle is a Sign vio_bundle
memoryIntegrity onlydigest only, no sig — mutable user data; carries an inline body plus its layer
modelIntegrity onlydigest and ref only, no sig — a reference to self-hosted weights you cannot author-sign

2.2 Two signing domains#

  • Per-artifact (sig). Each authored artifact is itself a Sign asset with its own signature, so it stays independently verifiable even when pulled out of this bundle — a signed prompt reused from a registry, for example. Algorithms per Sign algo_id: default 0x02 = RSA-2048 + ECDSA-P256; 0x04 = Ed25519; 0x03 = with Dilithium (post-quantum). The authoring tool runs the Sign ceremony when the artifact is authored.
  • Bundle (vio_bundle signature). The whole .vio is signed as one Sign vio_bundle asset over the canonical-YAML form of the manifest (canonicalize_vio_bundle(), RFC 8785). Because manifest.artifacts[] lists every artifact's digest, this single signature transitively binds all content — including the digest-only memory and model.

2.3 Why digest-only is still tamper-evident#

A model cannot be author-signed, but its digest sits inside the manifest that is signed as a vio_bundle. Tampering with the model on the target changes its hash; the manifest digest no longer matches; bundle verification fails. Reference-only artifacts therefore get integrity without authorship: provenance is not claimed, but tampering is caught. The model's inference descriptor lives in the manifest index entry, so it is covered directly by the bundle signature; the weights digest additionally catches tampering with the resolved weights on the target.

2.4 What is signed for a templated artifact#

The signed or digested content of a prompt or skill is the whole authored structure. For a prompt: mode, the system/user sections, the variables schema and default bindings. For a skill: its code or text plus its tools declaration (connector and scopes) — canonically serialized (RFC 8785), never the bound values or OAuth tokens. Consequences:

  • Tampering with a section, adding a stray {{slot}}, changing a variable's type, redirecting a binding (e.g. to a different secret://…), adding a tool or widening a connector scope → breaks the signature.
  • Filling {{client}} = "Acme", or injecting an OAuth token or tool result at runtime → does not touch the signature (values and credentials live outside the signed content).

So verification happens on the template; interpolation and framework assembly happen after verification, at instantiate or run. This is exactly why a finished string would be wrong — it would force re-signing per run, or leave injected values bound to an unverified blob.

3. Implemented subset#

The specification above is the full target. The current reference implementation exercises a deliberate subset of it. This section is the line between "the standard" and "what is built".

Implemented — the local compile-and-run path

  • A workspace (a folder of authored assets) compiles to a .vio: tree-shake (only assets reachable from the composed agents ship) → inline-resolve (resolve id-bound refs via the per-workspace discovery scan) → serialize to the YAML bundle above.
  • Run is compile-then-run, always, through .vio. A local run compiles the workspace to an unsigned, in-memory .vio and hands it to the local runner. This removes dev/prod drift — what you run locally is the same artifact shape you later deploy.
  • CrewAI only (framework: crewai); single-agent or within-crew composition.
  • Format features exercised: the manifest and artifact index; embedded prompt, skill and agent bodies; the templated-artifact model (sections, variables, bindings, two-facet output); id-based refs; memory bodies with layer; the models rail (self-hosted ref and descriptor) and the connector rail (hosted models and MCP tools resolved at run).

Specified, not yet built

  • Signing — the sig / vio_bundle signature representation (§2). The current compile produces an unsigned bundle; signing lands with the Sign substrate and the signed-deploy path.
  • Off-machine deploy — the deploy gates and the three destinations. The current path is local compile-and-run; signed .vio plus remote deploy sit later in the release train.
  • Multi-framework — LangChain, AutoGen and ACP adapters are future; the format is already neutral, only the CrewAI adapter is built.

4. Scope notes#

  • Memory ships an inline body. The format reserves type: memory and the store destination; a memory artifact carries its .memory.md text inline plus a layer declaring curated seed versus agent-local scratch (§1.8).
  • Model = reference, never payload. Weights are never embedded; a .vio carries a model://… ref, a digest and an inference descriptor on the manifest entry. Standing the model up is the deployer's job. Hosted models are not type: model — they ride the connector rail (§1.7).
  • Reserved compositions. prompt, skill, memory, model and bundle are valid compositions, but a standalone non-runnable artifact (a lone prompt, say) deploys to a registry, not a runtime.

5. Open questions#

  • Canonical-YAML edge cases for vio_bundle signing (block-scalar trailing-newline rules) — inherit Sign's canonicalizer exactly; pin a round-trip test.
  • Whether requires[] should also pin a registry coordinate (not just {ref, digest}) so a bundle can require an artifact that lives only in a registry, not inline. Leaning yes, post-v1.
  • Multi-agent crews (composition: bundle) — threading typed source: task results between agents; the run contract already covers it, the bundle composition surface is the open thread.

Proposals against any open question go through the process in Governance. Reserved values are listed in the Reference.

Field reference

Every key the .vio artifact format defines, where it lives, and the values it reserves. Filter by location or search by name.


Reserved values

A conforming reader treats any value outside these sets as reserved and rejects the bundle cleanly. New values are added by specification revision, never by a producer.

manifest.framework

crewai · langchain · autogen · claude-sdk · vercel-ai · adk (open set; adapters listed in Ecosystem)

manifest.composition

agent · prompt · skill · memory · model · bundle

artifacts[].type

prompt · skill · memory · model · agent

artifacts[].deploy

runtime · runtime/standalone · registry · store

skill.kind / skill.runtime

declarative · executable / python · js

variables[].source

input · env · task · connector · secret · static

tools[].kind

viorant · mcp

prompt.mode

chat · single_shot

memory.layer

seed (default) · runtime

signer.algo_id

0x02 RSA-2048 + ECDSA-P256 (default) · 0x04 Ed25519 · 0x03 with Dilithium

Integrate

Three ways to work with the .vio artifact format, in increasing depth: read it, verify it, deploy it. The first needs nothing you do not already have.

Read

Any YAML parser

Parse the document, walk manifest.artifacts[], inspect types, destinations and the capability surface. No dependency on any Viorant library.

  • Python: yaml.safe_load
  • Node: js-yaml
  • Go: gopkg.in/yaml.v3
  • Rust: serde_yaml
  • Dedicated .vio parser — coming soon
Verify

Viorant Sign

Optional. Recompute each artifact's digest over its canonical form, check per-artifact sig against the signer's registered key, and verify the vio_bundle signature over the canonical manifest. Verification is provided by Viorant Sign.

  • sign.viorant.ai — coming soon
  • Canonicalization: RFC 8785
  • Skill trees: sorted paths, per-file NFC
  • Memory: digest of { content } only
Deploy

Conforming deployer

Verify, then route each artifact by its declared deploy, resolve refs and connector auth on the target, and bind runtime values after verification.

  • Reference implementation: Helix
  • Gates: signature, reserved values, connector auth
  • Destinations: runtime, registry, store

Walk a bundle

The manifest index is the authoritative descriptor for every artifact, so most tooling never needs to open the bodies. The capability surface of the whole bundle is readable from manifest.requires[] and each skill's tools.

# python — list the capability surface of a bundle
import yaml

b = yaml.safe_load(open("agent.vio"))
assert b["vio"] == 1

for req in b["manifest"].get("requires", []):
    if "connector" in req:
        print("connector", req["connector"], req["scopes"], req["auth"])

for a in b["artifacts"]:
    if a["type"] == "skill":
        for t in a.get("tools", []):
            print("tool", a["id"], t["ref"], t["kind"], t.get("scopes"))
// node — separate signed from digest-only artifacts
import { readFileSync } from "node:fs";
import yaml from "js-yaml";

const b = yaml.load(readFileSync("agent.vio", "utf8"));
const index = b.manifest.artifacts;

const signed   = index.filter(a => "sig" in a);
const pinned   = index.filter(a => !("sig" in a));
const referred = index.filter(a => "ref" in a);

console.log({ signed: signed.map(a => a.id),
              pinned: pinned.map(a => a.id),
              referred: referred.map(a => a.ref) });

Open a .vio in your browser

This reader runs entirely in the page with a stock YAML parser. It checks the plain-YAML guarantee, the top-level shape, the manifest fields, the artifact index, reserved values and trust-tier consistency. It does not verify signatures — that requires the signer's public key.

Press Check to run the reader.

Converting from other agent formats

Declarative agent specifications that describe composition — which prompt, which tools, which model — map onto .vio artifacts directly. The format is designed as a target for conversion rather than a competitor: an existing definition becomes a bundle, gains a digest for every part and a signature for every authored part, and keeps its framework binding in manifest.framework.

Agent Format
Composition-level fields map to agent, prompt and skill artifacts; tool references become tools[] declarations with kind: mcp where a connector is implied.
planned
Open Agent Spec
Same mapping; model references classify as self-hosted (type: model) or hosted (connector rail) by whether weights are deployed.
planned
Oracle Agent Spec
Same mapping; typed outputs map to output.schema, prose expectations to output.expected.
planned
Framework-native YAML (CrewAI, LangChain, AutoGen)
Handled by framework adapters at instantiate rather than by conversion. The adapter assembles the native form from the neutral sections; the .vio stays framework-neutral.
CrewAI shipped

Ecosystem

What produces, signs, deploys and runs a .vio today — with status stated plainly. An implementation is listed as shipped only when it is in a released build.

Reference implementations

Viorant Hub
Producer. Authors prompts, skills, memory, models and agents in a workspace, tree-shakes and inline-resolves them, and compiles the workspace to a .vio bundle. Local runs compile-then-run through the same artifact shape; deployment ships the bundle to a run URL.
shipped · 1.6
Helix
Deployer. Consumes a .vio, verifies it via Sign, routes each artifact by its declared destination, resolves references and connector auth on the target, and binds runtime values after verification. One engine behind the vio CLI, the Helix MCP server and the Viorant Agent.
local path shipped
Viorant Sign
Optional signing and verification substrate at sign.viorant.ai. Defines vio_bundle as a first-class signable asset, canonicalize_vio_bundle() over RFC 8785, the key registry, verification engine, trust scoring and enforcement gate. The format is built to match its outputs.
coming soon
.vio parser
Dedicated library with typed access to the manifest, index and bodies, canonicalization and digest recomputation built in. A convenience layer over the plain-YAML guarantee, never a requirement to read a bundle.
coming soon
Viorant Cloud
Hosted runtime target. Receives deployed bundles and returns a run URL and run key; provider credentials stay encrypted locally and ride the connector rail.
shipped

Framework adapters

An adapter assembles a framework's native form from the neutral sections at instantiate. The bundle never changes; only the adapter does.

CrewAI
Single-agent and within-crew composition. output.expected folds into the Task's expected output; output.schema validates the result and wires source: task.
shipped
LangChain
Adapter not yet built. The format is already neutral; manifest.framework: langchain is a valid value.
planned
AutoGen
Adapter not yet built. manifest.framework: autogen is a valid value.
planned
Claude Agent SDK
Adapter not yet built. Proposed manifest.framework: claude-sdk; hosted Claude models ride the connector rail.
planned
Vercel AI SDK
Adapter not yet built. Proposed manifest.framework: vercel-ai; executable skills map to runtime: js.
planned
Google ADK
Adapter not yet built. Proposed manifest.framework: adk.
planned
ACP
Adapter not yet built.
planned

Connectors and integrations

A bundle exposes three things every surrounding tool can consume without parsing skill code: the capability surface in manifest.requires[] and each skill's tools, a digest for every artifact, and a declared destination for each. Connectors and integrations plug in on those three surfaces.

MCP connectors
Gmail, Slack, SerpAPI and any MCP-exposed tool. Pinned inside the signed skill as kind: mcp with connector and scopes; OAuth is resolved per deployment on the control plane and injected at run via connection://. Hosted models ride the same rail.
shipped
Observability
Every run carries the bundle id, version and per-artifact digests, so traces and evals attribute behavior to the exact signed prompt, skill and model descriptor that produced it. Adapters emit these as span attributes for tracing and evaluation platforms.
available
Security scanning
Scanners read the capability surface from the manifest before deploy: required connectors, requested scopes, executable skills and their runtimes. A widened scope or an undeclared tool is detectable without executing anything. Detection-rule engines can evaluate skill bodies as plain text.
available
Registries and stores
Artifacts with deploy: registry and deploy: store are addressable by digest; a registry can serve a signed prompt or skill to any bundle that pins it.
shipped

Licensing

Implementing the format is free, worldwide and royalty-free, and needs no agreement with anyone.

Specification, schema, examples, conformance
CC-BY-4.0. Attribution required; derivatives allowed.
open
Reference tooling, skills, website source
Apache-2.0 — chosen over MIT because MIT grants no patent rights, and a licensor holding a reading patent would otherwise leave implementers exposed.
open
Patent rights in the format
Royalty-free non-assertion covenant, scoped to conforming implementations, reciprocal, binding on successors. It does not extend to the Helix engine or the Sign substrate, which are separate patents and separate products.
covenant
.vio · VIO · the VIO Project · VIO Conformant
Trademarks of Viorant Inc., not licensed by either grant. Use the extension and say what is true, freely; claiming the certification mark requires passing the suite.
reserved

Adjacent work

Several open efforts describe an agent — its identity, capabilities, tools and permissions — as a schema. .vio occupies the layer after that one: packaging, pinning and provenance for the thing you deploy. They are complements, and a describing format is a natural conversion source (see Integrate).

Description formats
Agent Format, Agent Definition Language, agent cards and similar efforts declare what an agent is. None of them defines a signed, digest-pinned bundle, and none replaces one.
complementary
Provenance and supply chain
Digest pinning, canonicalization and detached signatures follow the same reasoning as software supply-chain provenance: sign what you author, pin what you reference, verify before you run.
aligned

Standards this format leans on

RFC 8785 — JSON Canonicalization Scheme

The canonical form every digest and signature is computed over, so cosmetic reformatting never invalidates a signature.

YAML 1.2 core schema

The portable subset the format restricts itself to. No anchors, aliases, custom tags or merge keys, by rule.

Model Context Protocol

Tools with kind: mcp are MCP connector tools; the connector and scopes are pinned inside the signed skill.

OCI images

Not the bundle — but the reference form for heavy skill trees and the deployer's pre-baked base images.

JSON Schema

The vocabulary of output.schema, the agent's typed output contract.

Semantic Versioning

Package identity in manifest.version. The format itself is versioned separately by the integer vio key.

Implementing the .vio artifact format?

Readers, verifiers, deployers, adapters and converters built against this specification are listed here once they pass the relevant conformance level. The process is described under Governance. Source, fixtures and issues live in the GitHub repository.

Conformance

Three levels, cumulative. Each is defined by what an implementation must accept, what it must reject, and what it must never do.

Level 1

Reader

  • Parses any bundle that meets the plain-YAML guarantee with a stock YAML 1.2 parser.
  • Requires vio to be an integer and rejects a version it does not implement.
  • Treats every value outside the reserved sets for composition, type, kind, runtime, deploy, source, tools[].kind, mode and layer as reserved, and rejects cleanly.
  • Reads a memory body with no layer as seed.
  • Never interprets a sig or digest as verified.
Level 2

Verifier

  • Everything in Level 1.
  • Recomputes each artifact's digest over its canonical form: RFC 8785 for structured content; sorted-path, per-file NFC map for skill trees; { content } only for memory.
  • Verifies per-artifact sig against the signer's registered key for the declared algo_id.
  • Verifies the vio_bundle signature over the canonical manifest, and therefore every listed digest.
  • Reports a digest mismatch on a digest-only artifact as a bundle verification failure, not a warning.
  • Never verifies over on-disk bytes; never accepts a signature computed over a rendered (interpolated) template.
Level 3

Deployer

  • Everything in Level 2, and verification precedes every other step.
  • Routes each artifact by its declared deploy value; never infers a destination.
  • Resolves refs on the target and checks the resolved bytes against the manifest digest before use.
  • Gates on manifest.requires[] connector dependencies: a required connection absent from the control plane blocks the deploy.
  • Binds input, secret, connector, env and task values after verification, never before; fails a run that omits a required input.
  • Materializes memory by layer and never overwrites an existing runtime object on redeploy.

VIO Conformant

Implementing the format is free and requires no agreement with anyone. Claiming the mark requires passing the suite — and nothing else.

Granted on evidence

Run the conformance cases at the level you claim and publish the output. Passing is the only requirement; a competitor of the reference implementer is entitled to the mark on identical terms.

Always qualified

"VIO Conformant — Level 1 (Reader), format version 1, revision 5." Never the bare mark: a claim without a level and a revision tells the reader nothing.

Lapses on revision

A claim lapses when the revision it was granted against is superseded by one that changes the cases it passed. Re-run, re-publish, re-claim.

The mark is the one thing the project controls. The specification, the schema and the reference tooling are open; the name is held so that "conformant" means something to the person reading it. Policy: TRADEMARKS.md.

Invariants every level shares

Secrets never enter the file

A bundle containing a literal credential where a secret:// or connection:// handle belongs is non-conforming, whatever its signatures say.

Capability is not widened silently

No implementation may grant a tool, connector or scope that is not declared in a signed skill and surfaced in manifest.requires[].

Weights are never embedded

A type: model artifact with a body is non-conforming. Models are references with descriptors.

Producers ship after consumers

A producer must not emit a field that the deployed consumer population rejects. The memory layer rollout is the reference case.

A machine-checkable conformance suite — fixture bundles per level, with expected accept/reject outcomes — is the next artifact this site will publish. Until it exists, the in-browser reader demonstrates Level 1 checks.

Contributors

Who wrote each revision of the specification, and who has contributed to the .vio artifact format since. Authorship is recorded per revision so that credit tracks the text, not the masthead.

Editors

Vivien Roggero

Editor · CEO and co-founder, Viorant

Format direction, positioning of the standard, governance and this site. Author on every published revision.

Adi Vora

Editor · CTO and co-founder, Viorant

Specification owner. Wrote the engineering text of revisions 1 through 4, ADR-035 and ADR-037, and the reference implementation in Hub and Helix.

Authorship by revision

Each row is one change to the specification text or to a decision record it derives from. A name on a row means that person authored or co-authored that change.

Revision 52026-09-22
VIO 1.0. The specification re-based onto the format as implemented and frozen. Digest subject specified in full; update/redeploy lifecycle and the agent body added; provider:// defined; the forward-compatibility claim corrected; version and signer corrected to optional; framework stated as closed. Schema, fixtures and linter regenerated from the reference implementation.
Adi VoraauthorVivien Roggeroreview
Revision 42026-09-04
§1.8 added — memory bodies declare a layer (seed | runtime), optional, default seed, outside the digest subject. Materialization, redeploy preservation and consumers-first rollout.
Adi VoraauthorVivien Roggeroreview
ADR-0372026 · accepted
File-based memory model — .md files, per-agent read and write sets, framework-neutral lowering. Basis for §1.8 and §4.
Adi Voraauthor
Revisions 2–32026-06 to 2026-08
Alignment of the text with ADR-035: two-tier trust, two signing domains, the templated-artifact model, skills as file trees, models rail and connector rail, decode-parameter precedence, the implemented-subset section.
Adi VoraauthorVivien Roggeroco-author
ADR-0352026-06-14 · accepted
.vio is a signed YAML artifact bundle deployed by Helix. Supersedes the format clause of ADR-010.
Adi VoraauthorVivien Roggeroco-author
Revision 12026-05-08
Specification created — full engineering text at target altitude with an explicit implemented-subset section.
Adi VoraauthorVivien Roggeroco-author
ADR-010retired
.vio as an OCI image with a manifest annotation. Superseded; recorded for provenance.
Adi Voraauthor

Contributors

Beyond the editors, contributions are credited by kind. A name appears here once a change has been accepted through the change process, an implementation has passed a conformance level, or a review has materially changed the text.

Specification text

Accepted proposals and revisions.

Vivien Roggero · Adi Vora

Reference implementation

Hub compiler, Helix deployer, adapters.

Adi Vora

Review

Technical review that changed the text.

None recorded yet beyond the editors.

Implementations

Conforming readers, verifiers, deployers, converters.

None external yet — see Ecosystem.

How to be listed

Propose a change

Open a proposal in the repository stating the problem, the alternatives considered and a compatibility statement. Accepted proposals credit the proposer on the revision that lands them.

Ship an implementation

Submit a reader, verifier, deployer, adapter or converter with its conformance level. Listed under Implementations and on the Ecosystem page.

Review a revision

Review that leads to a substantive change is credited on that revision as review.

Governance

Charter#

Editors: Vivien Roggero (CEO, Viorant) and Adi Vora (CTO, Viorant) author and maintain the specification. Authorship per revision is tracked on the Contributors page. The work is published as the VIO Project.

On the name. .vio takes its extension from Viorant, where the format originated. Verifiable Intelligence Object is a descriptive expansion adopted afterwards, not the origin of the letters. The format is maintained independently of any single implementation; the specification, this site and the repository are not hosted on a vendor domain.

The .vio artifact format exists so that an agent composed in one tool can be verified and deployed by another, without either reinventing the format. Its scope is packaging: how prompts, skills, memory, models and agents are bundled, digested and signed. It deliberately does not define cryptography (Sign), scheduling (deployers) or framework semantics (adapters).

Four commitments hold across revisions:

  1. Readable without us. The plain-YAML guarantee is not negotiable. A revision that requires format-specific tooling to parse is out of scope.
  2. Additive by default. New fields default to the behavior of bundles that omit them. The memory layer field — optional, defaulting to what existing bundles carried, outside the digest subject — is the template.
  3. Reserved, not ignored. Unknown values in enumerated fields cause rejection, never a guess. Silent acceptance is how a deployer mis-deploys.
  4. The built subset is published. The gap between the specification and its reference implementation is stated in the specification itself and kept current.

Change process#

Load-bearing decisions are recorded as numbered architecture decision records. A change to the format follows the path an ADR takes: proposal with the problem stated and alternatives named, review by the editors, acceptance with a date, and — where a decision supersedes an earlier one — an explicit note on the superseded record. The specification text then changes in a numbered revision that cites the ADR.

Proposals that touch the reserved value sets, the digest subject of any artifact type, or the canonical form must include a compatibility statement: what existing bundles do under the change, and whether producers or consumers ship first.

Versioning#

vio: N
The format version, an integer at the top of every bundle. It increments only when a reader built against the previous version could misread a bundle. Additive fields do not increment it.
Specification revision
The prose document carries a revision number and date. Revisions can add fields, tighten wording or record errata without changing vio.
manifest.version
The package's own semantic version, chosen by its author. Unrelated to the format version.

Changelog#

2026-09-22 · revision 5

VIO 1.0 — the specification re-based on the locked format

Revisions 1–4 were written at a target altitude and disagreed with the reference implementation in both directions. This revision describes the frozen format and nothing else. No part of it changes the format. The digest subject is specified in full (§2.2), the update lifecycle (§3) and the agent body (§1.9) are added, provider:// is defined, and the claim that the format grows without breaking older deployers is removed as false. Errata E-004 through E-008.

2026-09-04 · revision 4

Memory bodies declare a layer

Added §1.8. A memory artifact body carries layer: seed | runtime, optional, defaulting to seed, outside the digest subject. Materialization, redeploy preservation and consumers-first rollout specified.

2026-06-14 · ADR-035 accepted

.vio is a signed YAML artifact bundle

Supersedes the format clause of ADR-010. The bundle is a single self-contained YAML document; OCI relocates to deployer base images. Two-tier trust, two signing domains and the templated-artifact model recorded.

2026-05-08 · revision 1

Specification page created

First full engineering specification of the format, written at target altitude with an explicit implemented-subset section.

Earlier · ADR-010

.vio as an OCI image with a manifest annotation

Retired. Recorded here because bundles and documentation from that period exist; see Errata.

Errata#

RefAffectsCorrection
E-001Any material describing a .vio as an OCI image, or claiming docker pull / docker run of a .vioRetired by ADR-035. A .vio is a YAML bundle. OCI images are the reference form for heavy skill trees and the deployer's base images only.
E-002Statements that memory is body-less or reference-onlySuperseded. Memory artifacts carry an inline .memory.md body and a layer (rev. 4). The store destination and mem:// references remain valid.
E-003Any reading of memory layer as derived from an agent's read/write bindingLayer is declared on the asset, never derived from the binding. A write-bound seed memory is promoted to a runtime copy on first write; the seed is not mutated.

Glossary#

artifact
One of the five typed units a bundle packages: prompt, skill, memory, model, agent.
authored artifact
An artifact with a sig — prompt, skill or agent. You sign what you author.
binding
The mapping from a variable to its source; the explicit statement of what stays dynamic.
bundle
A whole .vio document; also the composition value for multi-agent packages.
canonical form
The RFC 8785 serialization that digests and signatures are computed over.
capability surface
The tools, connectors and scopes a skill declares — inside its signature.
connector
Org-scoped, OAuth-bound infrastructure resolved on the control plane; never packaged.
connector rail
The path by which hosted models and MCP tools receive credentials at run.
deploy
An artifact's declared destination: runtime, runtime/standalone, registry or store.
digest-only
An artifact with a digest and no sig — memory and model. Integrity without authorship.
layer
A memory body's declaration of seed (curated) or runtime (agent-local scratch).
models rail
The path by which self-hosted weights are resolved, stood up and digest-checked on the target.
reserved value
Any value outside a field's enumerated set. Rejected by conforming readers.
template
What is signed: sections, variable schema and bindings — never the rendered string.
tree-shake
Producer step that ships only assets reachable from the composed agents.
two-facet output
An agent's output.expected (prose, prompt-shaping) and output.schema (typed, validating).
VIO
Verifiable Intelligence Object — the expansion used as the format's tagline. See the note on the extension's origin under Charter.
vio_bundle
The Sign asset type for a whole bundle; its signature is computed over the canonical manifest.

Citation#

@techreport{vio-spec-2026,
  title   = {The .vio Artifact Specification},
  author  = {Roggero, Vivien and Vora, Adi},
  institution = {The VIO Project},
  year    = {2026},
  note    = {VIO 1.0. Format version 1, specification revision 5 (2026-09-22)},
  url     = {https://vioformat.org/spec}
}