VAL-AM — Action Manifest Specification
Version: 0.1 Status: Draft License: Apache License 2.0 Editor: Open VAL Foundation (pending donation; currently VAL Inc.)
1. Abstract
This specification defines the Action Manifest — a canonical, substrate-agnostic, JSON-LD-compatible document that describes any single intended action by an AI agent. The Action Manifest is the data structure on which all VAL policy decisions and receipts operate.
2. Goals
A conforming Action Manifest MUST:
- Be substrate-agnostic. A manifest produced by an Anthropic Claude agent and a manifest produced by an OpenAI GPT agent SHALL be indistinguishable in structure for the same logical action.
- Be content-deterministic. Given identical inputs, the manifest SHALL serialize to byte-identical JSON when canonicalized.
- Be hashable. The canonicalized form SHALL produce a stable cryptographic digest suitable for inclusion in a VAL-RF receipt.
- Be extensible without breaking compatibility. Additional fields MAY be added by operators in a namespaced extension space; conforming consumers SHALL ignore unknown fields.
- Be human-readable. The manifest SHALL be inspectable by an operator, auditor, or regulator without specialized tooling.
3. Terminology
The keywords MUST, MUST NOT, SHOULD, SHOULD NOT, REQUIRED, RECOMMENDED, MAY, and OPTIONAL are interpreted as in [RFC 2119].
- Agent. Any software process that emits actions on behalf of an operator. An agent has a stable identity.
- Operator. The legal entity (or natural person) that deploys an agent and is accountable for the agent's actions.
- Action. A discrete, named operation that the agent intends to perform against one or more targets, with one or more side effects.
- Manifest. A VAL-AM document describing a single intended action.
- Substrate. The underlying foundation model service or agent framework producing the action. Examples: Anthropic Claude, OpenAI GPT, Google Gemini, Meta Llama via vLLM, MCP-server-mediated calls.
- Adapter. A piece of code that translates substrate-native action descriptions (tool calls, function calls) into VAL-AM form.
4. Document Structure
A VAL-AM manifest is a single JSON object. Top-level fields:
4.1 REQUIRED fields
{
"@context": "https://val.run/ns/am/v0.1",
"@type": "ActionManifest",
"manifest_id": "<UUIDv7 string>",
"spec_version": "0.1",
"issued_at": "<RFC 3339 UTC timestamp>",
"agent": { ... },
"action": { ... },
"context": { ... }
}
4.1.1 manifest_id
A UUIDv7 (RFC 9562) generated by the adapter at the moment of manifest construction. UUIDv7 is REQUIRED rather than UUIDv4 because the embedded timestamp aids ordering in the receipt ledger. The manifest_id SHALL be globally unique.
4.1.2 spec_version
A string identifying the VAL-AM spec version the manifest conforms to. For this document, the value is "0.1".
4.1.3 issued_at
RFC 3339 timestamp in UTC, with millisecond precision, marking the moment the manifest was constructed by the adapter.
Example: "2026-06-07T14:23:51.482Z"
4.1.4 agent (object)
{
"id": "<stable agent identifier>",
"operator": "<operator URN>",
"deployment_id": "<environment-specific deployment identifier>",
"substrate": {
"vendor": "anthropic" | "openai" | "google" | "meta" | "xai" | "custom",
"model": "<vendor-specific model identifier>",
"version": "<vendor-specific version string>"
}
}
The agent.id SHALL be stable across a single deployment lifetime. The operator field MUST be a URN in the form urn:val:operator:<dns-name> (e.g., urn:val:operator:acme.example).
4.1.5 action (object)
{
"intent": "<intent category from VAL-AM Intent Ontology>",
"name": "<adapter-supplied human-readable action name>",
"targets": [ { ... }, ... ],
"side_effect": "reversible" | "slow_reversible" | "irreversible",
"risk_class": "low" | "medium" | "high" | "critical",
"value_at_risk": { ... } | null,
"payload_hash": "<SHA-256 hex digest of canonical payload>",
"payload_size_bytes": <integer>
}
4.1.6 context (object)
{
"request_id": "<adapter-supplied tracing ID>",
"parent_action_id": "<manifest_id of parent action, or null>",
"originating_human": "<URN identifying the human who initiated the chain, or null>",
"session_id": "<adapter-supplied session ID, or null>"
}
4.2 OPTIONAL fields
{
"tags": ["<arbitrary operator-supplied tag>", ...],
"extensions": {
"<namespace>": { ... }
}
}
Operators MAY include tags for routing or audit segmentation. Operators MAY include namespaced extensions for industry-specific or product-specific metadata. Namespaces SHOULD use reverse-DNS form (e.g., "com.acme.compliance"). Conforming policy engines and receipt verifiers SHALL ignore unrecognized namespaces.
5. The Intent Ontology
The action.intent field MUST take a value from the VAL-AM Intent Ontology, a stable, extensible vocabulary of intent categories. The v0.1 ontology defines the following categories:
| Intent | Description |
|---|---|
query_information | Read-only retrieval. No state change. |
send_communication | Outbound message (email, SMS, push, chat, post, etc.) |
mutate_data | Create, update, or delete data in a system of record |
financial_transaction | Movement of money, credits, or financial instruments |
deploy_code | Modify or deploy software, infrastructure, or configuration |
provision_resource | Allocate, deallocate, or modify compute/storage/network resources |
submit_artifact | Submission of a document, filing, or artifact to an external authority |
purchase_goods | Procurement of goods or services |
negotiate_contract | Creation, modification, or commitment to a contractual obligation |
interact_physical | Trigger an action in the physical world (IoT, robotics) |
delegate_to_agent | Spawning, instructing, or invoking another agent |
escalate_to_human | Routing decision to a human reviewer |
terminate_process | Stopping or pausing a process, system, or agent |
other | Anything that does not map to the above (SHOULD include a tag for classification) |
The ontology is extensible via the VAL-AM RFC process. Implementations SHOULD treat unknown intent values as "other" for policy fallback purposes.
6. Targets
Each entry in action.targets is an object describing a resource, person, or system affected by the action.
{
"type": "<target type URI>",
"identifier": "<system-specific identifier>",
"display_name": "<human-readable name, OPTIONAL>",
"count": <integer, OPTIONAL>,
"scope": "individual" | "group" | "broadcast"
}
The type field SHALL be a URI from one of:
- A well-known target type URI from the VAL-AM Target Type Registry (e.g.,
https://val.run/ns/target/user,https://val.run/ns/target/customer,https://val.run/ns/target/database,https://val.run/ns/target/email_address,https://val.run/ns/target/file,https://val.run/ns/target/api_endpoint,https://val.run/ns/target/payment_account). - A custom URI in operator-controlled namespace.
The scope field has these semantics:
individual— one specific target instance.group— a named group with bounded membership (e.g., a customer segment).broadcast— an unbounded or very large audience.
The count field, when present, gives the actual or estimated number of distinct target instances affected. For broadcast scope, count MAY exceed any operator-set threshold and MUST be honestly reported by the adapter.
7. Value at Risk
The action.value_at_risk field captures a dimensional estimate of consequence if the action proceeds incorrectly. It is either null (no quantifiable risk) or an object:
{
"dimension": "currency" | "record_count" | "person_count" | "exposure_class",
"amount": <number>,
"unit": "<unit string, e.g., USD, EUR, records, persons>",
"confidence": "exact" | "estimated" | "upper_bound" | "lower_bound"
}
Examples:
- A wire transfer of $4,200 USD:
{"dimension": "currency", "amount": 4200, "unit": "USD", "confidence": "exact"} - A marketing email to ~12,500 customers:
{"dimension": "person_count", "amount": 12500, "unit": "persons", "confidence": "estimated"} - A schema migration touching an unknown number of rows in a large table:
{"dimension": "record_count", "amount": 10000000, "unit": "records", "confidence": "upper_bound"}
Adapters SHOULD compute value_at_risk from the action payload when possible. When the value is not derivable, adapters MAY default to null and rely on policy escalation for safety.
8. Side Effect Class
The action.side_effect field captures the reversibility profile of the action:
| Value | Definition |
|---|---|
reversible | The action can be undone by a routine inverse action, with no externally visible cost. |
slow_reversible | The action can be undone, but the undo is expensive, slow, or visible to third parties (e.g., refunding a payment, recalling an email). |
irreversible | The action cannot be undone by any technical means available to the operator (e.g., a wire transfer to an external bank, a permanently deleted record without backup, a published broadcast). |
The adapter SHOULD select the most conservative value when there is uncertainty.
9. Payload Hashing
The action.payload_hash field is the SHA-256 hex digest of the canonicalized action payload. The canonical payload is the substrate-native action body (e.g., the OpenAI function-call arguments, the Anthropic tool_use input, the MCP request body) serialized as RFC 8785 JSON Canonicalization Scheme (JCS) UTF-8 bytes.
The payload itself is NOT included in the manifest. Only its hash. This serves three purposes:
- Privacy. The payload may contain sensitive customer data; the manifest can be retained and audited without retaining the payload.
- Compactness. The manifest is small and indexable independent of payload size.
- Provability. A receipt referring to this manifest_id implicitly attests to the payload's content at the moment the action was decided.
If the operator wants to retain the payload, they MAY do so separately and link it via an extension namespace (e.g., "extensions": {"com.operator.payload_storage": {"uri": "s3://..."}}).
10. Canonicalization
For hashing and for receipt binding, the manifest MUST be canonicalized via RFC 8785 JSON Canonicalization Scheme (JCS) before serialization to bytes.
JCS requires:
- UTF-8 encoding
- Lexicographic key ordering (recursively)
- No insignificant whitespace
- Specific number formatting per IEEE 754 / I-JSON
The canonical hash of the manifest is:
manifest_hash = SHA-256(JCS-serialize(manifest))
This hash is referenced by VAL-RF receipts to bind a receipt to a specific manifest.
11. Worked Example
A customer support agent (built on Anthropic Claude, running in operator "Acme Software") is about to issue a $4,200 USD refund to customer C-19384 via Stripe.
{
"@context": "https://val.run/ns/am/v0.1",
"@type": "ActionManifest",
"manifest_id": "01963d2a-1c5f-7c4b-9d34-2a8be1a45c01",
"spec_version": "0.1",
"issued_at": "2026-06-07T14:23:51.482Z",
"agent": {
"id": "support-fleet/refund-handler-v3",
"operator": "urn:val:operator:acme.example",
"deployment_id": "prod-us-east-1",
"substrate": {
"vendor": "anthropic",
"model": "claude-opus-4-7",
"version": "claude-opus-4-7"
}
},
"action": {
"intent": "financial_transaction",
"name": "stripe.refund.create",
"targets": [
{
"type": "https://val.run/ns/target/customer",
"identifier": "customer:C-19384",
"display_name": "C. Wright",
"scope": "individual"
},
{
"type": "https://val.run/ns/target/payment_account",
"identifier": "stripe:acct_1Hxxxxx",
"scope": "individual"
}
],
"side_effect": "slow_reversible",
"risk_class": "medium",
"value_at_risk": {
"dimension": "currency",
"amount": 4200,
"unit": "USD",
"confidence": "exact"
},
"payload_hash": "f3b5a9c8e7d4a6b2c1f8e9d0a3b6c5d4e7f2a1b8c5d6e9f0a3b6c5d4e7f2a1b8",
"payload_size_bytes": 184
},
"context": {
"request_id": "req_8KdL2nXz4pWqMyRtVa3b",
"parent_action_id": null,
"originating_human": "urn:val:user:acme.example:customer:C-19384",
"session_id": "sess_ZxQw9aBcD8eFgHiJkLmN"
},
"tags": ["support", "refund", "tier-1"]
}
12. Conformance
An implementation conforms to VAL-AM v0.1 if:
- It emits manifests with all REQUIRED fields populated according to the type definitions above.
- It uses values from the v0.1 Intent Ontology (or
"other"with a clarifying tag). - It canonicalizes manifests via RFC 8785 JCS before hashing.
- It produces SHA-256 payload hashes from RFC 8785 JCS canonicalized payloads.
- It treats unknown extension namespaces and unknown intent values as opaque (does not reject manifests on the basis of unrecognized extensions).
Adapters SHOULD additionally pass the VAL-AM Conformance Test Suite (published separately) before claiming conformance.
13. Security Considerations
- The
agent.idandagent.operatorfields are unauthenticated by VAL-AM alone. Identity authentication is the responsibility of the layer above (typically the agent identity provider or VAL-RF signing key control). VAL-AM defines the data model; VAL-RF defines the cryptographic binding. - Adapters running inside the agent's process boundary are part of the trust base. An adapter that lies about
intent,value_at_risk, ortargetsdefeats the entire substrate. Operators SHOULD prefer adapters distributed by the substrate vendor or by the Open VAL Foundation reference implementation. - The
payload_hashfield reveals nothing about the payload content except a hash collision (negligible probability under SHA-256). Operators concerned about hash-and-test attacks against low-entropy payloads MAY include a randomly generated salt in the payload prior to hashing. - Manifests SHOULD be transmitted to policy engines over authenticated channels. Manifests in transit are not signed by VAL-AM itself; signing is the receipt's job.
14. Privacy Considerations
- Manifests intentionally omit payload bodies to reduce the audit log's PII footprint.
- Target
identifiervalues may themselves be PII (e.g., email addresses, customer IDs). Operators SHOULD select a target identifier scheme that minimizes PII exposure while preserving auditability — for example, opaque pseudonymous IDs rather than raw email addresses, with the mapping retained in operator-controlled storage. - The
context.originating_humanURN MAY identify a natural person. Operators subject to GDPR or similar regimes SHOULD ensure manifest retention is compatible with their data subject rights obligations.
15. IANA / Registry Considerations
The Open VAL Foundation maintains the VAL-AM Intent Ontology Registry and the VAL-AM Target Type Registry. Additions and deprecations follow the foundation's RFC process. v0.1 of this spec ships with the baseline registries documented in Sections 5 and 6.
16. Change Log
- v0.1 (2026): Initial publication.
17. References
- [RFC 2119] Key words for use in RFCs to Indicate Requirement Levels
- [RFC 3339] Date and Time on the Internet
- [RFC 8785] JSON Canonicalization Scheme (JCS)
- [RFC 9562] Universally Unique IDentifiers (UUIDs) — UUIDv7
- VAL-CPL — Conduct Policy Language (this repository)
- VAL-RF — Receipt Format (this repository)
End of VAL-AM v0.1.