Skip to content

spec: post-meeting converged AI Card profile proposal#18

Open
muscariello wants to merge 21 commits intomainfrom
feat/proposal-postmeeting
Open

spec: post-meeting converged AI Card profile proposal#18
muscariello wants to merge 21 commits intomainfrom
feat/proposal-postmeeting

Conversation

@muscariello
Copy link

Summary

This PR adds a new post-meeting specification proposal that converges the current AI Card draft direction into a single profile focused on:

  1. Modeling both live services and at-rest assets.
  2. Preserving protocol autonomy through delegated extension modules.
  3. Supporting multiple discovery and distribution technologies.
  4. Strengthening identity and cryptographic provenance guidance.
  5. Providing a practical migration path from previous draft variants.

What is included

  • specification/sep-0015-converged-ai-card-profile.md

    • Draft proposal for a converged AI Card profile.
    • Normative-style requirements for core envelope, modules, locators, trust/signatures, and conformance levels.
    • Discovery bindings for HTTP well-known catalog and registry publishing.
    • Migration guidance from previous services/interfaces/protocols-style drafts.
  • specification/schema/schema.json

    • JSON Schema for converged AI Card payloads.
  • specification/schema/catalog-schema.json

    • JSON Schema for converged AI catalog payloads.
  • specification/cddl/ai-card-profile.cddl

    • CDDL for converged AI Card payloads.
  • specification/cddl/ai-catalog.cddl

    • CDDL for converged AI catalog payloads.
  • specification/examples/converged-live-service-card.json

    • Example live-service card with delegated protocol modules and multiple locators.
  • specification/examples/converged-data-asset-card.json

    • Example data-asset card with immutable artifact references.
  • specification/examples/converged-ai-catalog.json

    • Example catalog containing both live-service and data-asset entries.
  • README.md

    • Added links to the new draft specification and artifacts.

Key proposal decisions in this PR

  1. Introduce cardKind (live-service, data-asset, hybrid) to support both runtime and at-rest use cases.
  2. Use modules[] as the primary delegation mechanism so protocol/domain owners evolve independently.
  3. Keep trust and provenance first-class (trust, signatures) while allowing phased adoption via conformance levels (L0..L3).
  4. Treat HTTP well-known and registry publication as complementary bindings for the same logical card content.

What is intentionally not finalized yet

  1. Canonical signature format requirements for v1.
  2. Module namespace governance model.
  3. Final versioning policy for cardVersion.

$schema: text,
specVersion: text,
cardVersion: text,
cardKind: "live-service" / "data-asset" / "hybrid",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Collaborator

@mindpower mindpower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

  1. Keep the artifacts: [* Artifact] array at the root level for static data downloads (the 'nouns').
  2. Restore the protocols: { "mcp": {...}, "a2a": {...} } map for live endpoints (the 'verbs'). This gives each protocol a clean, isolated namespace.
  3. 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?

@muscariello
Copy link
Author

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.

@mindpower
Copy link
Collaborator

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 cardKind for that O(1) early filtering so the registry doesn't have to parse the whole payload is a great optimization.

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?

  1. Keep cardKind at the root: This gives the registry the exact early-filtering index it needs to know what it's dealing with before parsing the payload.
  2. Replace the flat locators array with protocols (for live APIs) and artifacts (for static data): This fixes the routing ambiguity. If the router pulls a live-service, it instantly grabs protocols.a2a or protocols.mcp without having to loop through generic locators to guess the transport. If it pulls a data-asset, it just grabs the artifacts array.

This way, the Registry gets its fast filtering, the Router gets its strict typing without guessing, and the unified Trust block at the root handles provenance for both use cases.

Does that sounds good to you?

@muscariello
Copy link
Author

Let me take into account your feedback @mindpower.
I realize the map you are proposing contains multiple cards so cardKind does not make sense.

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.
These labels could be standardized to summarize the entire collection of inner cards as we should assume every project would have a specific way to label their own card. A2A uses skills, but they might be others in general.

Have a look at the next commit.

Signed-off-by: Luca Muscariello <muscariello@ieee.org>
@mindpower
Copy link
Collaborator

mindpower commented Mar 5, 2026

This latest commit looks fantastic, @muscariello ! We are practically 100% converged. Dropping the rigid cardKind and bringing back the map structure completely solves the routing ambiguity we discussed. Combined with the tags you included earlier, this perfectly aligns with the extensible routing and registry discovery goals we originally set out to achieve.

I just have one minor structural thought, and a quick procedural suggestion:

1. The modules wrapper: Do we gain much by nesting protocols and artifacts inside a generic modules object? (i.e., card.modules.protocols.a2a vs card.protocols.a2a). Usually, keeping primary domain concepts at the root level reduces parsing friction for clients. If we just promote protocols and artifacts directly to the root (right next to tags and publisher), it keeps the JSON incredibly clean and flat.

2. Preserving the Working Group History:
Since this converged schema now beautifully reflects the isolated namespaces and core identity blocks we've been hammering out (plus your excellent addition of the artifacts array!), how do you want to handle the merge? The original PR #4 currently holds 70+ comments of deep architectural history and consensus-building from both the working group and the broader open-source community.

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>
@muscariello
Copy link
Author

@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"
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@mindpower
Copy link
Collaborator

@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.

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 modules wrapper: I definitely see your point about insulating parsers from future additions. My lean towards a flat structure (promoting protocols and artifacts directly to the root) is mostly inspired by how OpenAPI or Kubernetes handle top-level extensions - it usually keeps the base types a bit cleaner for developers to read. Since it's a question of taste, maybe we can keep it flat for simplicity in v1? It's usually easier to add a wrapper later than to remove one once parsers are built. But I'm completely open to whatever the broader group prefers!

2. On Naming:
I saw your notes on naming in the latest commit, great catches. I’ll take a detailed look at those today and drop my thoughts so we can nail down the exact taxonomy.

Next Steps:
To keep things moving and save you from cross-fork Git headaches, I'll review your naming comments today and apply those tweaks along with the flattened root, and pull your converged CDDL directly merge into PR #4? I will make sure you are tagged as a co-author on the commit as well.

}

HostInfo = {
name: text,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

displayName


HostInfo = {
name: text,
? id: text,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identifier for the catalog. Could be a DID.

AICatalog = {
$schema: text,
specVersion: text,
host: HostInfo,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed on the call "host" might not be the right name here, "publisher" the same as we have in the card is closer to what we want.

records: [* CatalogEntry]
}

HostInfo = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the AI Catalog contain the FQDN, which would tie the ai catalog to the domain? This might not be desirable.

],
"modules": {
"artifacts": {
"dataset": {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this key? And how is it different than the Id of the artifact?

AICatalog = {
$schema: text,
specVersion: text,
host: HostInfo,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

name: text,
description: text,
? tags: [* text],
cardUrl: text,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-known location where ai-catalog.json can be found
  • We want a way to get from ai-catalog.json to an instance of an MCP Server Card
  • So if this cardUrl can be an MCP Server Card (perhaps with an additional protocol field 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)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Copy link
Author

@muscariello muscariello Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

mindpower added a commit to mindpower/ai-card that referenced this pull request Mar 5, 2026
…update naming from PR Agent-Card#18

Co-authored-by: Luca Muscariello <lumuscar@cisco.com>
@mindpower
Copy link
Collaborator

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.

Tehsmash added 2 commits March 9, 2026 11:56
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.
Tehsmash and others added 4 commits March 9, 2026 12:03
- 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>
muscariello and others added 10 commits March 10, 2026 10:24
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants