spec: post-meeting converged AI Card profile proposal#18
spec: post-meeting converged AI Card profile proposal#18muscariello wants to merge 28 commits intomainfrom
Conversation
| $schema: text, | ||
| specVersion: text, | ||
| cardVersion: text, | ||
| cardKind: "live-service" / "data-asset" / "hybrid", |
There was a problem hiding this comment.
I think tying the entire card to a single cardKind at the root level might create a false dichotomy. As mentioned by Mauro in the discussion doc, an AI service often has both: it might expose a 'live-service' via an A2A endpoint for real-time inference, but also offer a 'data-asset' (like downloading its specialized skills, artifacts) via a Skills.
I see hybrid was added here to handle services that are both data-assets and live-services. However, from a routing / client use perspective, hybrid creates ambiguity.
If a caller sees cardKind: "hybrid", it still has to iterate through the flat locators array and write custom logic to guess which URL is the live API and which URL is the data download.
| ? trust: Trust, | ||
| ? signatures: [* Signature], | ||
| ? modules: [* Module], | ||
| ? locators: [* Locator], |
There was a problem hiding this comment.
Following up on the overall review comment: if an agent supports both the MCP protocol and the A2A protocol, or the one A2A could have multiple endpoints uris, flattening all endpoints into a single locators array means a router has to inspect each locator to figure out which protocol it belongs to.
If we wrap these inside a protocols: { "mcp": {...}, "a2a": {...} } map, the router or client can instantly grab the exact endpoints and artifacts it needs for the protocol it speaks, and ignore the rest.
There was a problem hiding this comment.
Hey @muscariello , thanks for putting this converged view together! I'm really glad to see we are completely aligned on the core structural objects here - the Publisher, Trust, and Attestation blocks look great and match the #4 proposal perfectly.
I also completely agree with your addition of the artifacts array. Having a dedicated way to reference static data (like model weights, datasets, or static skill files) is a great addition.
My main piece of feedback is regarding the transport/endpoint layer. I notice this drops the protocols map from PR #4 in favor of moving locators, artifacts, and modules to the root level alongside a cardKind enum (live-service, data-asset, hybrid).
My concern is that flattening this creates ambiguity for routers / clients, especially with the hybrid designation. If an agent exposes both an MCP protocol and an A2A protocol, a flattened locators array forces the routing client to loop through every URL and guess which endpoint belongs to which protocol based on the URI or media type. It breaks the strong typing we achieved in the core objects.
Could we look at a 'best of both' approach?
- Keep the artifacts: [* Artifact] array at the root level for static data downloads (the 'nouns').
- Restore the protocols: { "mcp": {...}, "a2a": {...} } map for live endpoints (the 'verbs'). This gives each protocol a clean, isolated namespace.
- Drop the cardKind enum and the generic locators array. If a card has artifacts, we know it has data assets. If it has protocols, we know it's a live service. If it has both, it's natively a 'hybrid' without needing a string enum to tell the router to guess.
This keeps the strict typing you aimed for, but ensures the transport layer remains cleanly isolated. What are your thoughts on combining these approaches?
|
The reason I added the card kind was to manage more general cases where you have an MCP card as data asset and also as live services. The current MCP registry is about data assets with a mix of live services too. To learn more about the kind of card you need to scan inside, and therefore you cannot filter early. I am not sure my intent was to flatten, I am mostly concerned about discriminating live vs data. The main reason for that is that the security model is very different for these two use case: one is authentication the other is mostly provenance. |
Ah, that makes complete sense for the registry layer . Having I would gently push back on one nuance, though: in a zero-trust Agentic world, live services also heavily rely on provenance. Authentication alone isn't enough for an agent API - we still need supply-chain provenance (like AI-BOMs, signed build manifests, or base model attestations) to actually trust the live inference endpoint. But your core point about early filtering sounds right. What if we combine both of our goals to satisfy both the Registry and the router?
This way, the Registry gets its fast filtering, the Router gets its strict typing without guessing, and the unified Does that sounds good to you? |
|
Let me take into account your feedback @mindpower. We can keep the map like you proposed. I would call this map "modules" to contains "protocols", "artifacts" and more in the future. This means that locators are only part of the inner cards as it would not make much sense to have different locators listed outside of the map. I have a concern about announce and discovery. An outer card (say an ai record) in a catalog which contains several other cards needs a labels which can be used to announce and discover this object beyond the simple index. Have a look at the next commit. |
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
|
This latest commit looks fantastic, @muscariello ! We are practically 100% converged. Dropping the rigid I just have one minor structural thought, and a quick procedural suggestion: 1. The 2. Preserving the Working Group History: Would you be open to pushing this final, converged CDDL (with the flattened root) directly into PR #4? That way, we keep all the rich historical context and decision logs attached to the final merge, rather than fragmenting it. Either way, incredible work pulling all these threads together! Let me know what you think. |
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
|
@mindpower I am fine with any approach to merge. I can redirect to PR #4, no problem. I am trying to make sure I am including all the discussion points. Hope to get more feedback too. I am not sure modules is actually required but it has some value as interface if we start adding and deprecating protocols in the future as this avoid to change parsers to some extent. But it's a question of taste probably. In this latest commit I added some comments to your other PR on naming. I had some concerns that I shared in here. Hope you can have a look at this. |
| "type": "https", | ||
| "role": "api", | ||
| "uri": "https://api.acme-finance.com/a2a/v1" | ||
| } |
There was a problem hiding this comment.
Something we've done in the a2a AgentCard is move the protocol version down into the locator (AgentInterface), this allows for a single agent to serve multiple A2A protocol versions cleanly which is required for backwards compatiblity / safe rolling upgrades etc.
Should "data" here really just be the AgentCard embedded in the ai card? If so we should fix the example to align it properly with the AgentCard schema. Similarly we should make sure the "data" for MCP is aligned with the MCP server card.
Awesome, really appreciate you being open to using PR #4 to preserve the community history, @muscariello ! And thank you for doing the heavy lifting to synthesize all these discussion points - it’s incredibly helpful for the working group. 1. On the 2. On Naming: Next Steps: |
specification/cddl/ai-catalog.cddl
Outdated
| } | ||
|
|
||
| HostInfo = { | ||
| name: text, |
specification/cddl/ai-catalog.cddl
Outdated
|
|
||
| HostInfo = { | ||
| name: text, | ||
| ? id: text, |
There was a problem hiding this comment.
Identifier for the catalog. Could be a DID.
specification/cddl/ai-catalog.cddl
Outdated
| records: [* CatalogEntry] | ||
| } | ||
|
|
||
| HostInfo = { |
There was a problem hiding this comment.
Should the AI Catalog contain the FQDN, which would tie the ai catalog to the domain? This might not be desirable.
| ], | ||
| "modules": { | ||
| "artifacts": { | ||
| "dataset": { |
There was a problem hiding this comment.
What is this key? And how is it different than the Id of the artifact?
specification/cddl/ai-catalog.cddl
Outdated
| AICatalog = { | ||
| $schema: text, | ||
| specVersion: text, | ||
| host: HostInfo, |
There was a problem hiding this comment.
Sorry commented on the wrong PR, lifting here:
Can host be optional? I think many MCP use cases would not care to populate this, so not sure we want this to be a required field.
specification/cddl/ai-catalog.cddl
Outdated
| name: text, | ||
| description: text, | ||
| ? tags: [* text], | ||
| cardUrl: text, |
There was a problem hiding this comment.
Sorry commented on the wrong PR, lifting here --
Could we consider allowing pointing to an MCP Server Card (or A2A Agent Card) directly here?
This is probably tied to the uncertainty around "do we definitely want/need an envelope AI card format". If we were to adopt the shared extension approach @ToddSegal brought up in the first call, we wouldn't need the AI card intermediating here.
From my POV, for much of what MCP wants out of discovery:
- It would be sufficient to have a
.well-knownlocation whereai-catalog.jsoncan be found - We want a way to get from
ai-catalog.jsonto an instance of an MCP Server Card - So if this cardUrl can be an MCP Server Card (perhaps with an additional
protocolfield of some sort), I think that's likely to work for us, and we accomplish our shared goal of having a unified discovery layer.
This current model requires an extra hop, to go ai-catalog.json -> AI Card -> MCP Server Card. And the current proposal for AI Card has shapes/duplication of values we intend to (additionally?) store in MCP Server Card, and I'm not sure we'd want to combine governance of those fields to be in the critical path of discovery.
Pushing for alignment on all of AI Card's current scope will be a long road, I think. For example, I think tags, maturity, logoUrl, etc all require discussion that we've discussed at length in various ways within the MCP ecosystem. And if we strip out all the controversial things that require alignment, I worry we end up with a very thin AI Card layer (in which case why not sidestep all that coordination and just link to MCP Server Cards / A2A Agent Cards directly here)?
There was a problem hiding this comment.
@tadasant this is a reasonable concern. What you describe is similar to a manifest file, with referrers to cards which exist as atomic and independent unit. In that case the ai-catalog or the ai-card seems like the same thing. Let me try to propose something that addresses these concerns.
There was a problem hiding this comment.
@tadasant @mindpower @darrelmiller @ToddSegal
We believe the current manifest approach addresses all concerns and requirements raised so far by the participating projects and individual contributors:
- Delegation: each card has a media type owned and managed by its project.
- The AI Card spec only needs to track media types.
- The AI Card is a flat manifest collection of referrers by digest, making it globally unique and secure.
- The catalog is fully portable and location-independent, and can be hosted statically or behind an API server for convenience.
- Provenance is supported out of the box, and multiple attestations can be added incrementally.
…update naming from PR Agent-Card#18 Co-authored-by: Luca Muscariello <lumuscar@cisco.com>
|
Hey @muscariello , just a quick update: Based on discussions #18 (comment). I've pulled the converged CDDL into PR #4! I went ahead and flattened the protocols and artifacts up to the root (dropping the modules wrapper) as we discussed, and I also added you as a Co-Author on the commit and also updated you as an Assignee on that PR so we can drive it across the finish line together. Whenever you are ready, feel free to close this PR out, and we can continue the final naming/polish discussions over on #4 where all the historical context lives. Thanks again for driving this convergence. |
Replace the custom card/catalog model with a proper OCI-native design: - AI Card → AI Manifest (OCI Image Manifest with artifactType) - AI Card Config moves to a dedicated config blob - Modules → typed OCI layers (A2A, MCP, ModelPack dataset) - AI Catalog → OCI Image Index - Signing removed from config; replaced by OCI Referrers (cosign/notation) - cardKind dropped; inferred from layers present Add statically hosted registry binding rooted at /.well-known/ai-registry, implementing the read-only OCI Distribution Spec subset (end-1/2/3/8a/12a/b) with a /_catalog.json entry point for zero-configuration discovery. Update schemas (schema.json, catalog-schema.json), add config-schema.json, update CDDL definitions, and rewrite all examples to match.
- Replace proposal frontmatter with Version/Status/Authors header - Add Abstract section - Add RFC 2119 conformance language (Section 1) - Remove 'This proposal defines' / 'This profile defines' language throughout - Drop Open Questions section - Rename 'Summary' -> 'Abstract', 'Discovery Bindings' -> 'Distribution', 'Design Principles' -> 'Design Goals' - Tighten MUST/SHOULD/MAY normative language in data model sections - Fix schema/example paths to be relative to specification/
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
feat(spec): rewrite SEP-0015 as OCI-native AI Manifest spec
…ing from PR #18 Co-authored-by: Luca Muscariello <lumuscar@cisco.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
docs(spec): patch specs with auto-discovery and app-usage
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
Signed-off-by: Ramiz Polic <ramiz.polic@hotmail.com>
|
Hi @muscariello and @ramizpolic , first off, thank you for putting this together. This is an incredibly thorough and elegant application of the OCI specification. Moving the enterprise trust, signing (via cosign/notation), and distribution into standard OCI registries makes perfect sense for heavy, enterprise-grade AI asset management. As I digest this, I want to make sure we don't accidentally kill the grassroots adoption we are seeing from the MCP, A2A and web-native developer communities. For many of those developers, standing up an OCI registry or understanding Image Manifests just to share a simple agent card introduces too much friction. They love the simplicity of hosting a static Proposed Architectural Framing:
By treating OCI as a powerful storage/distribution profile rather than the only data model, we satisfy Enterprise's need for strict supply-chain security without scaring away the lightweight Agent developers. What are your thoughts on framing this as an advanced distribution profile alongside the baseline we just merged? Happy to jump on a call to whiteboard how they map to each other! |
|
@mindpower there is no need to stand an OCI server. Try to reproduce the small demo. You can have an OCI layout w/o a server. I have concerns about the fact that we have lined up all the requirements which are common to OCI and will inevitable lead to redoing OCI but not as good. In that case OCI is a better option as we have to write no code. So IMO, this proposal can be used in a purely static way as the OCI layout is a list of files in a folder. My claim is that this proposal covers all the requirements combined without adding complexity. |
In addition to what @muscariello said, most developers should never need to interact directly with the proposed structure unless they are building a CLI, library or registry on top of the spec which needs to understand the structure in order to navigate it. For most agentic developers there should be tooling, libraries, or CLIs to interact with the ai-card catalog/registry whether static or dynamic. For example: If you're using modelpack to publish a model you create a Modelfile (like a Dockerfile) and go through modctl which packs the data into the OCI structure and uses ORAS underneath. You also use modctl to pull from the registry static local or remote and extract the model back into a directory. I envision the ecosystem will be similar for AI Card as for modelpack, and if we use the same structure for static and for dynamic catalogs then the same tooling can be used for both at least from a reader client's perspective. |
Summary
This PR adds a new post-meeting specification proposal that converges the current AI Card draft direction into a single profile focused on:
Overview
This PR rewrites the SEP-0015 converged AI Card profile as an OCI-based specification, replacing the custom card/catalog model with one that follows OCI Image and Distribution specification. The result is that common AI metadata is natively storable, distributable, and signable in any OCI registry without any custom tooling.
What changes
Data model
The top-level AI Card document becomes a standard OCI Image Manifest, identified as an AI Manifest by its artifactType (
application/vnd.aaif.ai.manifest.v1+json). Common metadata like identity and publisher details is moved into a dedicated config blob (application/vnd.aaif.ai.card.metadata.v1+json). Protocol-specific metadata (A2A, MCP) and data asset references become typed OCI layer blobs, with artifactTypes owned by this spec but content schemas owned by the respective upstream projects. The AI Catalog becomes a standard OCI Image Index.The data model can be expressed using a MerkleDAG:
graph TB subgraph Catalog["OCI Index"] AICatalog["AI Catalog"] end AICatalog --> AIM1["AI Manifest 1"] AICatalog --> AIMn["AI Manifest N"] subgraph Manifest1["OCI Manifest"] AIM1 --> Config1["AI Card Metadata"] AIM1 --> Layer1A["A2A Card"] AIM1 --> Layer1B["AGNTCY DIR Record"] Config1 ~~~ Layer1A ~~~ Layer1B end subgraph ManifestN["OCI Manifest"] AIMn --> ConfigN["AI Card Metadata"] AIMn --> LayerN1["MCP Server"] AIMn --> LayerN2["HuggingFace Model"] ConfigN ~~~ LayerN1 ~~~ LayerN2 end subgraph AppLayer["OCI Referrers"] Ext1["Signature"] Ext2["Identity Claims"] end Ext1 --> AIM1 Ext2 --> AIMn style Catalog fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f style Manifest1 fill:#dcfce7,stroke:#22c55e style ManifestN fill:#dcfce7,stroke:#22c55e style AppLayer fill:#fef3c7,stroke:#f59e0bSigning
The embedded
signaturesarray and the associated subject commitment model are removed entirely. Signing and attestation are handled via the OCI Referrers API using cosign or notation, following the same pattern already used for signing container images.Discovery
A new statically hosted registry binding is defined, rooted at
/.well-known/ai-registry. This implements the read-only subset of the OCI Distribution Spec (manifest fetch, blob fetch, tags list, referrers list). For static only serving,_catalog.jsonis defined which serves AI Catalog file (OCI Index). Dynamic autodiscovery is also supported through a common subject descriptor included in the AI Manifest and works out-of-box with existing OCI registries.Spec document
The document is refactored from a proposal into a normative specification: RFC 2119 conformance language, an Abstract section, a Related Work section referencing CNCF ModelPack/AGNTCY DIR, removal of Open Questions, and updated conformance levels (L0–L3).