Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# ADR-0021: Separate Artifact Identity from Registry Coordinates

**Status:** Proposed

**Date:** 2026-08-26

**Related:** [Issue #102](https://github.com/Agent-Card/ai-catalog/issues/102)

**Supersedes if accepted:** The federated AIR requirement in
[ADR-0015](0015-agent-identifier-naming.md)

## Context

Existing registries commonly identify artifacts with native coordinates,
such as a registry namespace and artifact name. When projecting those
records as AI Catalog entries, a registry may have no publisher-assigned
`urn:air` identifier.

Using the registry's domain in `urn:air` is easy, but the current format
defines that domain as the artifact publisher. Requiring the publisher's
domain is portable, but prevents automatic projection when the publisher
has not supplied or authorized an identifier.

The existing model already separates most roles: `publisher` identifies
the artifact publisher, `host` identifies the catalog operator, `url`
locates the artifact, and `extensions` can preserve registry-specific
coordinates.

## Decision

`entry.identifier` identifies the artifact represented by the entry and
remains stable across versions and catalog locations. Consumers that do
not recognize its identifier scheme treat the value as opaque.
Identifier syntax alone does not verify publisher identity or establish
trust.

The base format does not require a particular identifier scheme. A
globally unique absolute URI is recommended for open or federated use.
Publisher-controlled `urn:air` identifiers remain recommended when
available.

A registry uses a stateful preserve-or-mint policy:

1. Reuse any primary identifier it previously published for the artifact.
2. Otherwise, preserve a publisher-assigned identifier when the source is
authorized to use that identifier or namespace.
3. Otherwise, assign and persist a stable identifier in a namespace the
registry controls.

A registry does not silently replace a primary identifier it has already
published, including when an authorized publisher-assigned identifier
becomes available later. Changing the primary identifier requires an
explicit migration mechanism, which this decision does not define.

The registry assigning an identifier, the catalog `host`, and the
artifact `publisher` are independent roles. A registry-issued identifier
does not imply that the registry published the artifact.

Registry-native coordinates belong in a namespaced entry extension when
needed for lookup or round trips. They do not affect catalog uniqueness
or establish publisher identity, trust, or equivalence with another
identifier.

## Consequences

- Existing authorized publisher identifiers can be preserved across
registries and mirrors.
- Legacy records can be projected without publisher enrollment by using
a registry-issued identifier.
- Two registries may assign different identifiers to the same artifact
when no publisher-assigned identity is available. The model does not
claim equivalence it cannot establish.
- No new core field is added; native coordinates use `extensions`.
- Generic aliases and primary-identifier migration remain future work.

## Alternatives Considered

Always using a registry-domain `urn:air` was rejected because it makes the
registry appear to be the artifact publisher under the current format.

Requiring a publisher-domain `urn:air` was rejected as a universal rule
because it makes automatic projection depend on publisher enrollment.

Adding `aliases`, `nativeIdentifier`, or `identifiers[]` was deferred
because registry coordinates do not necessarily assert logical identity
equivalence, and `extensions` is sufficient for the immediate use case.
52 changes: 50 additions & 2 deletions specification/ai-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ A Catalog Entry object describes a single AI artifact in the catalog.
It MUST contain the following members:

`identifier`
: A string uniquely identifying this artifact. This field is an open text format (e.g., any valid URI or URN is accepted). However, to ensure interoperability, identity uniqueness, and discoverability, the standard `urn:air` naming structure is **HIGHLY RECOMMENDED** and **MUST** be used for open or federated systems.
: A string uniquely identifying this artifact. This field is an open text format (e.g., any valid URI or URN is accepted). Consumers that do not recognize an identifier scheme MUST treat the value as opaque. Identifier syntax alone does not verify publisher identity or establish trust. For open or federated systems, a globally unique absolute URI is RECOMMENDED. The `urn:air` naming structure is RECOMMENDED when the publisher assigns an identifier in a namespace it controls.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is the main change to call out. From:

the standard urn:air naming structure is HIGHLY RECOMMENDED and MUST be used for open or federated systems

to:

For open or federated systems, a globally unique absolute URI is RECOMMENDED. The urn:air naming structure is RECOMMENDED when the publisher assigns an identifier in a namespace it controls.

The rationale being: federated registries should not invent a urn:air identifier for a publisher when the publisher hasn't provided such an identifier for a legacy artifact. See #102 for more info.


**Standard Naming Format:**
`urn:air:{publisher}:{namespace}:{name}`
Expand All @@ -219,7 +219,7 @@ It MUST contain the following members:

For closed or local systems where a different identifier format is used, client implementations are responsible for parsing and processing the custom format as appropriate.

See [Multi-Version Entries](#multi-version-entries) for uniqueness rules when multiple versions are present.
See [Multi-Version Entries](#multi-version-entries) for uniqueness rules when multiple versions are present, and [Registry Projection](#registry-projection) for identifiers assigned while projecting an existing registry.

`type`
: A string containing the identifier that specifies the type of the
Expand Down Expand Up @@ -469,6 +469,54 @@ For example, a catalog listing two versions of the same agent:
Both entries share the same `identifier` but have distinct `version`
values, so the combination is unique.

## Registry Projection
Comment thread
jonathanhefner marked this conversation as resolved.
Outdated

A registry projecting existing records MUST reuse any primary identifier
it previously published for the artifact. On first publication,
it SHOULD preserve a publisher-assigned identifier when the source is
authorized to use that identifier or namespace. Otherwise, it SHOULD
assign and persist a stable identifier in a namespace the registry
controls. A registry MUST NOT infer namespace authorization from the
artifact's URL or an unsigned `publisher` field.

A registry MUST NOT silently replace a previously published primary
identifier, including when an authorized publisher-assigned identifier
becomes available later. Adopting a different primary identifier requires
an explicit migration mechanism, which this specification does not define.

A registry-assigned identifier identifies the artifact, not a particular
version or registry record. It MUST remain stable across
versions, registry-coordinate changes, and retrieval-URL changes, and
MUST NOT be reassigned to another artifact. The registry assigning the
identifier, the catalog `host`, and the artifact `publisher` are
independent roles.

Registry-native coordinates SHOULD be preserved in a namespaced entry
extension when needed for lookup or round trips. They do not participate
in catalog uniqueness or establish publisher identity, trust, or
equivalence with another identifier.

```json
{
"identifier": "https://registry.example/ids/artifacts/7bf4a8c2",
"type": "application/a2a-agent-card+json",
"url": "https://registry.example/apis/registry/v3/groups/payments/artifacts/fraud-agent",
"publisher": {
"identifier": "did:web:acme.example",
"displayName": "Acme"
},
"extensions": {
"com.example.registry.coordinates": {
"registryUri": "https://registry.example",
"namespace": "payments",
"name": "fraud-agent"
}
}
}
```

The extension key is illustrative.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As we're aware that AI catalog is designed for federation, do you think it makes sense to formalise a native/official extension for federation source / entry origin?

This could then be used to build chain of origin if someone wants to find the normative source of a entry, e.g. resolve the entry origin then check that entries origin until you find an entry with no origin.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I pushed a commit to address the other comments, but I think this comment should be addressed in a separate PR if we want to pursue it.


## Publisher Object

The Publisher object identifies the entity responsible for an artifact.
Expand Down
Loading