-
Notifications
You must be signed in to change notification settings - Fork 36
Separate artifact identity from registry coordinates #105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
6d24850
b69d2b9
dbd96af
5db970b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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. | ||
|
|
||
| **Standard Naming Format:** | ||
| `urn:air:{publisher}:{namespace}:{name}` | ||
|
|
@@ -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 | ||
|
|
@@ -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 | ||
|
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. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
|
|
||
There was a problem hiding this comment.
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:
to:
The rationale being: federated registries should not invent a
urn:airidentifier for a publisher when the publisher hasn't provided such an identifier for a legacy artifact. See #102 for more info.