From 6d24850fbc058362b40a62f1243ffb56680f1c03 Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Wed, 26 Aug 2026 15:27:50 -0500 Subject: [PATCH 1/4] Separate artifact identity from registry coordinates Clarify how a registry creates AI Catalog entries for existing artifacts that lack publisher-assigned `urn:air` identifiers. Preserve authorized publisher identifiers when available; otherwise assign and persist a registry-controlled identifier without conflating the registry with the artifact publisher. Keep native registry coordinates in namespaced `extensions`, treat unrecognized schemes as opaque, and defer identifier migration rather than silently changing published identifiers. --- ...fact-identity-from-registry-coordinates.md | 86 +++++++++++++++++++ specification/ai-catalog.md | 52 ++++++++++- 2 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 adr/0021-separate-artifact-identity-from-registry-coordinates.md diff --git a/adr/0021-separate-artifact-identity-from-registry-coordinates.md b/adr/0021-separate-artifact-identity-from-registry-coordinates.md new file mode 100644 index 0000000..fa87e1d --- /dev/null +++ b/adr/0021-separate-artifact-identity-from-registry-coordinates.md @@ -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. diff --git a/specification/ai-catalog.md b/specification/ai-catalog.md index b8b3837..e80a125 100644 --- a/specification/ai-catalog.md +++ b/specification/ai-catalog.md @@ -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 + +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. + ## Publisher Object The Publisher object identifies the entity responsible for an artifact. From b69d2b9344ff71a6c536e503353eaa9ac06ebdc9 Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Thu, 27 Aug 2026 13:53:19 -0500 Subject: [PATCH 2/4] Clarify identifier portability rules Define publisher-authorized `urn:air` identifiers as the portable form that catalogs preserve on first incorporation, while allowing registries to preserve or replace non-AIR identifiers. Distinguish registries acting as artifact publishers, authorized delegates, and independent hosts; specify the corresponding `{publisher}` segment rules; and make retention of replaced source identifiers optional in namespaced `extensions`. --- ...fact-identity-from-registry-coordinates.md | 64 ++++++++++++------- specification/ai-catalog.md | 60 +++++++++++------ 2 files changed, 80 insertions(+), 44 deletions(-) diff --git a/adr/0021-separate-artifact-identity-from-registry-coordinates.md b/adr/0021-separate-artifact-identity-from-registry-coordinates.md index fa87e1d..1ce1a97 100644 --- a/adr/0021-separate-artifact-identity-from-registry-coordinates.md +++ b/adr/0021-separate-artifact-identity-from-registry-coordinates.md @@ -29,47 +29,65 @@ 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. +remains stable across versions. A publisher-authorized `urn:air` +identifier is also portable across catalog locations. Other +identifier schemes remain valid but have no cross-catalog portability +guarantee. Consumers that do not recognize an 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. +An artifact publisher that wants an identifier to be preserved when the +artifact appears in other catalogs should use the AI Catalog-specific +`urn:air` format in a namespace it controls. -A registry uses a stateful preserve-or-mint policy: +A publisher-authorized `urn:air` identifier is one assigned by the +artifact publisher or its authorized delegate, with the artifact +publisher's domain in the `{publisher}` segment. -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 uses a stateful preserve-or-mint policy: -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. +1. If the registry previously published an identifier for the artifact, + reuse it, even if another identifier becomes available later. +2. Otherwise, if the source entry contains a publisher-authorized + `urn:air` identifier, preserve it exactly. +3. Otherwise, the registry may preserve or replace a non-`urn:air` source + identifier. Non-`urn:air` identifiers have no guaranteed portability + across catalogs. +4. When assigning a new identifier, a registry that becomes the artifact + publisher should use `urn:air` with its own domain in the `{publisher}` + segment. A registry acting as an authorized delegate should use + `urn:air` with the delegating publisher's domain in that segment. An + independent registry must use a non-`urn:air` identifier under its own + control. + +Merely hosting or aggregating an entry does not make a registry the +artifact publisher. + +Changing a previously published 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. +A registry may retain replaced source identifiers or registry-native +coordinates. When retained, they should be stored in a namespaced entry +extension. 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 +- Publisher-authorized `urn:air` identifiers are preserved across registries and mirrors. +- Non-`urn:air` identifiers remain valid, but registries may replace them + when they are unsuitable for the destination catalog. - 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. + when no publisher-authorized `urn:air` 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. diff --git a/specification/ai-catalog.md b/specification/ai-catalog.md index e80a125..88a026c 100644 --- a/specification/ai-catalog.md +++ b/specification/ai-catalog.md @@ -203,9 +203,9 @@ 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). 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. +: 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. An artifact publisher that wants an entry identifier to be preserved when the artifact appears in other catalogs SHOULD use the AI Catalog-specific `urn:air` naming structure with its own domain in the `{publisher}` segment. A catalog incorporating an entry for the first time with a publisher-authorized `urn:air` identifier MUST preserve that identifier exactly. - **Standard Naming Format:** + **AI Catalog Publisher Naming Format:** `urn:air:{publisher}:{namespace}:{name}` - `{publisher}`: The domain name of the organization publishing the artifact (e.g., `example.com`). @@ -433,9 +433,9 @@ single artifact — similar to a package registry. When `version` is present, the combination of `identifier` and `version` MUST be unique within the catalog. When `version` is absent, `identifier` -alone MUST be unique. The `identifier` SHOULD be stable across versions -and catalog locations so that the same logical artifact can be -recognized wherever it appears. +alone MUST be unique. The `identifier` SHOULD be stable across versions. +Only publisher-authorized `urn:air` identifiers receive a cross-catalog +preservation requirement, as defined in [Registry Projection](#registry-projection). Clients that need only the latest version SHOULD sort entries sharing the same `identifier` by `version` (when parseable as a semantic @@ -471,18 +471,35 @@ values, so the combination is unique. ## Registry Projection -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 publisher-authorized `urn:air` identifier is one assigned by the +artifact publisher or its authorized delegate, with the artifact +publisher's domain in the `{publisher}` segment. + +A registry creating an entry from an existing record or catalog entry +MUST select its primary identifier by applying these rules in order: + +1. If the registry previously published an identifier for the artifact, + it MUST reuse that identifier, even if another identifier becomes + available later. +2. Otherwise, if the source entry contains a publisher-authorized + `urn:air` identifier, it MUST preserve the identifier exactly. +3. Otherwise, the registry MAY preserve a non-`urn:air` source identifier + or replace it. Non-`urn:air` identifiers have no guaranteed portability + across catalogs. +4. When assigning a new identifier, a registry that becomes the artifact + publisher SHOULD use `urn:air` with its own domain in the `{publisher}` + segment. A registry acting as an authorized delegate SHOULD use + `urn:air` with the delegating publisher's domain in that segment. An + independent registry MUST use a non-`urn:air` identifier under its own + control. + +Merely hosting or aggregating an entry does not make a registry the +artifact publisher. +A registry MUST NOT infer publisher authorization from the artifact's URL +or an unsigned `publisher` field. + +Adopting a different primary identifier after publication 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 @@ -491,10 +508,10 @@ 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. +A registry MAY retain replaced source identifiers or registry-native +coordinates. If retained, they SHOULD be stored in a namespaced entry +extension. They do not participate in catalog uniqueness or establish +publisher identity, trust, or equivalence with another identifier. ```json { @@ -508,6 +525,7 @@ equivalence with another identifier. "extensions": { "com.example.registry.coordinates": { "registryUri": "https://registry.example", + "sourceIdentifier": "foo", "namespace": "payments", "name": "fraud-agent" } From dbd96afdd7c0ed93a6cfa58825f7e049ca93909b Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Fri, 28 Aug 2026 10:46:10 -0500 Subject: [PATCH 3/4] Clarify catalog projection terminology Frame identifier selection as catalog projection performed by a catalog operator, rather than only as registry behavior, and distinguish source Catalog Entries from source-system records. Name the `urn:air` identifier format explicitly and scope the ordered selection rules to first incorporation so later source changes remain governed by identifier stability rather than implicit artifact-equivalence assumptions. --- ...fact-identity-from-registry-coordinates.md | 58 ++++++++++--------- specification/ai-catalog.md | 54 +++++++++-------- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/adr/0021-separate-artifact-identity-from-registry-coordinates.md b/adr/0021-separate-artifact-identity-from-registry-coordinates.md index 1ce1a97..c1185a3 100644 --- a/adr/0021-separate-artifact-identity-from-registry-coordinates.md +++ b/adr/0021-separate-artifact-identity-from-registry-coordinates.md @@ -13,8 +13,8 @@ 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. +records as AI Catalog entries, the catalog operator 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 @@ -46,33 +46,34 @@ A publisher-authorized `urn:air` identifier is one assigned by the artifact publisher or its authorized delegate, with the artifact publisher's domain in the `{publisher}` segment. -A registry uses a stateful preserve-or-mint policy: +Catalog projection creates a Catalog Entry from either a source Catalog +Entry in another AI Catalog or a source record in another system. When +incorporating a projected entry for the first time, a catalog operator +selects its identifier by applying these rules in order: -1. If the registry previously published an identifier for the artifact, - reuse it, even if another identifier becomes available later. -2. Otherwise, if the source entry contains a publisher-authorized - `urn:air` identifier, preserve it exactly. -3. Otherwise, the registry may preserve or replace a non-`urn:air` source - identifier. Non-`urn:air` identifiers have no guaranteed portability +1. If the source contains a publisher-authorized `urn:air` identifier, + preserve it exactly. +2. Otherwise, the operator may preserve a non-`urn:air` source identifier + or replace it. Non-`urn:air` identifiers have no guaranteed portability across catalogs. -4. When assigning a new identifier, a registry that becomes the artifact +3. When assigning a new identifier, an operator that becomes the artifact publisher should use `urn:air` with its own domain in the `{publisher}` - segment. A registry acting as an authorized delegate should use + segment. An operator acting as an authorized delegate should use `urn:air` with the delegating publisher's domain in that segment. An - independent registry must use a non-`urn:air` identifier under its own - control. + operator that is neither the artifact publisher nor its authorized + delegate must use a non-`urn:air` identifier under its own control. -Merely hosting or aggregating an entry does not make a registry the +Operating a catalog or aggregating an entry does not make its operator the artifact publisher. Changing a previously published 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. +The catalog operator and artifact publisher are distinct roles. An +operator-assigned identifier does not imply that the operator published +the artifact. -A registry may retain replaced source identifiers or registry-native +A catalog operator may retain replaced source identifiers or source-system coordinates. When retained, they should be stored in a namespaced entry extension. They do not affect catalog uniqueness or establish publisher identity, trust, or equivalence with another identifier. @@ -80,15 +81,15 @@ identity, trust, or equivalence with another identifier. ## Consequences - Publisher-authorized `urn:air` identifiers are preserved across - registries and mirrors. -- Non-`urn:air` identifiers remain valid, but registries may replace them - when they are unsuitable for the destination catalog. + catalogs and mirrors. +- Non-`urn:air` identifiers remain valid, but catalog operators may preserve + or replace them. - 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-authorized `urn:air` identity is available. The model - does not claim equivalence it cannot establish. -- No new core field is added; native coordinates use `extensions`. + an operator-assigned identifier. +- Two catalog operators may assign different identifiers to the same + artifact when no publisher-authorized `urn:air` identity is available. + The model does not claim equivalence it cannot establish. +- No new core field is added; source-system coordinates use `extensions`. - Generic aliases and primary-identifier migration remain future work. ## Alternatives Considered @@ -100,5 +101,6 @@ 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. +because source-system coordinates do not necessarily assert logical +identity equivalence, and `extensions` is sufficient for the immediate +use case. diff --git a/specification/ai-catalog.md b/specification/ai-catalog.md index 88a026c..b37c74e 100644 --- a/specification/ai-catalog.md +++ b/specification/ai-catalog.md @@ -203,9 +203,9 @@ 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). 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. An artifact publisher that wants an entry identifier to be preserved when the artifact appears in other catalogs SHOULD use the AI Catalog-specific `urn:air` naming structure with its own domain in the `{publisher}` segment. A catalog incorporating an entry for the first time with a publisher-authorized `urn:air` identifier MUST preserve that identifier exactly. +: 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. An artifact publisher that wants an entry identifier to be preserved when the artifact appears in other catalogs SHOULD use the AI Catalog-specific `urn:air` naming structure with its own domain in the `{publisher}` segment. A catalog operator incorporating an entry for the first time with a publisher-authorized `urn:air` identifier MUST preserve that identifier exactly. - **AI Catalog Publisher Naming Format:** + **`urn:air` Identifier Format:** `urn:air:{publisher}:{namespace}:{name}` - `{publisher}`: The domain name of the organization publishing the artifact (e.g., `example.com`). @@ -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, and [Registry Projection](#registry-projection) for identifiers assigned while projecting an existing registry. + See [Multi-Version Entries](#multi-version-entries) for uniqueness rules when multiple versions are present, and [Catalog Projection](#catalog-projection) for identifiers assigned while projecting an existing Catalog Entry or source-system record. `type` : A string containing the identifier that specifies the type of the @@ -435,7 +435,7 @@ When `version` is present, the combination of `identifier` and `version` MUST be unique within the catalog. When `version` is absent, `identifier` alone MUST be unique. The `identifier` SHOULD be stable across versions. Only publisher-authorized `urn:air` identifiers receive a cross-catalog -preservation requirement, as defined in [Registry Projection](#registry-projection). +preservation requirement, as defined in [Catalog Projection](#catalog-projection). Clients that need only the latest version SHOULD sort entries sharing the same `identifier` by `version` (when parseable as a semantic @@ -469,46 +469,44 @@ 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 +## Catalog Projection A publisher-authorized `urn:air` identifier is one assigned by the artifact publisher or its authorized delegate, with the artifact publisher's domain in the `{publisher}` segment. -A registry creating an entry from an existing record or catalog entry -MUST select its primary identifier by applying these rules in order: +Catalog projection creates a Catalog Entry from either a source Catalog +Entry in another AI Catalog or a source record in another system. When +incorporating a projected entry for the first time, a catalog operator +MUST select its identifier by applying these rules in order: -1. If the registry previously published an identifier for the artifact, - it MUST reuse that identifier, even if another identifier becomes - available later. -2. Otherwise, if the source entry contains a publisher-authorized - `urn:air` identifier, it MUST preserve the identifier exactly. -3. Otherwise, the registry MAY preserve a non-`urn:air` source identifier +1. If the source contains a publisher-authorized `urn:air` identifier, + the operator MUST preserve it exactly. +2. Otherwise, the operator MAY preserve a non-`urn:air` source identifier or replace it. Non-`urn:air` identifiers have no guaranteed portability across catalogs. -4. When assigning a new identifier, a registry that becomes the artifact +3. When assigning a new identifier, an operator that becomes the artifact publisher SHOULD use `urn:air` with its own domain in the `{publisher}` - segment. A registry acting as an authorized delegate SHOULD use + segment. An operator acting as an authorized delegate SHOULD use `urn:air` with the delegating publisher's domain in that segment. An - independent registry MUST use a non-`urn:air` identifier under its own - control. + operator that is neither the artifact publisher nor its authorized + delegate MUST use a non-`urn:air` identifier under its own control. -Merely hosting or aggregating an entry does not make a registry the -artifact publisher. -A registry MUST NOT infer publisher authorization from the artifact's URL -or an unsigned `publisher` field. +Operating a catalog or aggregating an entry does not make its operator the +artifact publisher. A catalog operator MUST NOT infer publisher +authorization from the artifact's URL or an unsigned `publisher` field. Adopting a different primary identifier after publication 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. +An identifier assigned by a catalog operator identifies the artifact, not +a particular version or source record. It MUST remain stable across +versions, source-coordinate changes, and retrieval-URL changes, and MUST +NOT be reassigned to another artifact. The catalog operator and artifact +publisher are distinct roles. The operator is the entity identified by the +top-level `host` field when that field is present. -A registry MAY retain replaced source identifiers or registry-native +A catalog operator MAY retain replaced source identifiers or source-system coordinates. If retained, they SHOULD be stored in a namespaced entry extension. They do not participate in catalog uniqueness or establish publisher identity, trust, or equivalence with another identifier. From 5db970bc56a50f6c30397e344f29f70827e89187 Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Mon, 31 Aug 2026 08:36:40 -0700 Subject: [PATCH 4/4] Cross-reference Trust Manifest identity validation Point catalog projection readers to the existing trust-domain alignment requirement when a projected `urn:air` entry includes a Trust Manifest. Keep the normative validation rule in `Identity` as the single source of truth rather than duplicating or reinterpreting it. --- specification/ai-catalog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/specification/ai-catalog.md b/specification/ai-catalog.md index b37c74e..3e99f16 100644 --- a/specification/ai-catalog.md +++ b/specification/ai-catalog.md @@ -492,6 +492,9 @@ MUST select its identifier by applying these rules in order: operator that is neither the artifact publisher nor its authorized delegate MUST use a non-`urn:air` identifier under its own control. +A projected entry that uses `urn:air` and includes a Trust Manifest remains +subject to the trust-domain alignment requirements in [Identity](#identity). + Operating a catalog or aggregating an entry does not make its operator the artifact publisher. A catalog operator MUST NOT infer publisher authorization from the artifact's URL or an unsigned `publisher` field.