Description
Unify provider-profile identity around the OpenShell resource convention and make profile references explicitly workspace-aware.
ProviderProfile was introduced as an unscoped catalog value with a logical id. Custom profile storage later wrapped it in StoredProviderProfile.metadata, copying profile.id into metadata.name. Providers now refer to that same logical key through Provider.type, with the profile scope carried separately in Provider.profile_workspace.
The resulting identity model has several names for the same value and two meanings of id:
provider.type == profile.id == stored_profile.metadata.name
stored_profile.metadata.id == opaque resource UUID
For user-managed profiles, the actual reference is composite:
(provider.profile_workspace, provider.type)
->
(stored_profile.metadata.workspace, stored_profile.metadata.name)
This is easy for both humans and agents to misuse. It has also allowed runtime catalog code to erase profile scope and index entries only by normalized profile ID.
Context
This cleanup does not need to preserve the existing provider-profile wire or file shape. Do not add compatibility aliases, fallback lookup paths, or data backfills; update the model and its consumers atomically.
Proposed Direction
-
Separate profile specification from profile identity. For example, introduce a ProviderProfileSpec containing credentials, endpoints, binaries, discovery, and presentation fields.
-
Use ObjectMeta.name as the canonical name for stored user-managed profile resources. Keep ObjectMeta.id as the opaque resource UUID.
-
Introduce one typed profile key/reference containing scope and canonical name. Provider runtime code should resolve profiles through this type rather than passing bare strings:
ProfileKey {
scope: Platform | Workspace(name) | WorkspaceAgnostic,
name: NormalizedProfileName,
}
-
Have profile sources return entries that retain scope and source provenance. Built-in and interceptor-provided entries should be represented explicitly as workspace-agnostic/source-managed rather than relying on implicit fallback behavior.
-
Key EffectiveProviderProfileCatalog by the typed profile key and require provider resolution, policy composition, refresh, environment resolution, and revision hashing to use the provider's complete profile reference.
-
Separate effective-catalog discovery from exact-scope user-profile CRUD, or otherwise make the read semantics explicit. CLI preflight and runtime creation must observe the same effective catalog; mutation APIs must target only mutable user-managed resources in the requested scope.
-
Rename or restructure Provider.type and Provider.profile_workspace so the protobuf expresses a single profile reference instead of two independently interpreted fields.
-
Update profile YAML, CLI output/input, protobufs, architecture documentation, published provider documentation, and interceptor contracts to use the new terminology consistently.
Definition of Done
Description
Unify provider-profile identity around the OpenShell resource convention and make profile references explicitly workspace-aware.
ProviderProfilewas introduced as an unscoped catalog value with a logicalid. Custom profile storage later wrapped it inStoredProviderProfile.metadata, copyingprofile.idintometadata.name. Providers now refer to that same logical key throughProvider.type, with the profile scope carried separately inProvider.profile_workspace.The resulting identity model has several names for the same value and two meanings of
id:For user-managed profiles, the actual reference is composite:
This is easy for both humans and agents to misuse. It has also allowed runtime catalog code to erase profile scope and index entries only by normalized profile ID.
Context
ProviderProfile.idoriginated when profiles were catalog payloads rather than stored resources: feat(providers): add profile-backed policy composition #1037.StoredProviderProfile { ObjectMeta metadata; ProviderProfile profile; }was added with the custom registry: feat(providers): add custom profile registry #1170.ProviderProfilevalues.This cleanup does not need to preserve the existing provider-profile wire or file shape. Do not add compatibility aliases, fallback lookup paths, or data backfills; update the model and its consumers atomically.
Proposed Direction
Separate profile specification from profile identity. For example, introduce a
ProviderProfileSpeccontaining credentials, endpoints, binaries, discovery, and presentation fields.Use
ObjectMeta.nameas the canonical name for stored user-managed profile resources. KeepObjectMeta.idas the opaque resource UUID.Introduce one typed profile key/reference containing scope and canonical name. Provider runtime code should resolve profiles through this type rather than passing bare strings:
Have profile sources return entries that retain scope and source provenance. Built-in and interceptor-provided entries should be represented explicitly as workspace-agnostic/source-managed rather than relying on implicit fallback behavior.
Key
EffectiveProviderProfileCatalogby the typed profile key and require provider resolution, policy composition, refresh, environment resolution, and revision hashing to use the provider's complete profile reference.Separate effective-catalog discovery from exact-scope user-profile CRUD, or otherwise make the read semantics explicit. CLI preflight and runtime creation must observe the same effective catalog; mutation APIs must target only mutable user-managed resources in the requested scope.
Rename or restructure
Provider.typeandProvider.profile_workspaceso the protobuf expresses a single profile reference instead of two independently interpreted fields.Update profile YAML, CLI output/input, protobufs, architecture documentation, published provider documentation, and interceptor contracts to use the new terminology consistently.
Definition of Done
ProviderProfile.idis removed rather than mirrored intometadata.name.