Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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,7 @@
---
'@red-hat-developer-hub/backstage-plugin-catalog-backend-module-ai-resource-agent': minor
---

Add `AiResourceAgentProcessor` to validate agent-specific fields on
`kind: AiResource` entities with `spec.type: agent` at catalog ingestion.
Register the processor alongside the existing agent catalog model source.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@red-hat-developer-hub/backstage-plugin-catalog-backend-module-ai-resource-extensions': minor
---

Use the valid catalog kind spelling `AiResource` (not `AIResource`) in the
extensions processor, and rename public exports accordingly:
`AiResourceExtensionsProcessor` and `AiResourceScope`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@red-hat-developer-hub/backstage-plugin-catalog-model-ai-resource-agent': minor
'@red-hat-developer-hub/backstage-plugin-catalog-backend-module-ai-resource-agent': minor
---

Make `spec.instructions` optional on agent AiResource entities so agents
with a baked-in default prompt can be registered without a catalog-side
system prompt.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# Shape follows the upstream skill/rule discriminated-type pattern from
# @backstage/catalog-model alpha (kind: AiResource, spec.type: agent)
# plus RHDH optional extensions (spec.scope for AIResourceExtensionsProcessor).
# plus RHDH optional extensions (spec.scope for AiResourceExtensionsProcessor).
#
# Demonstrates a router + specialist multi-agent handoff pattern using only
# the design D3 field set (no Augment-only keys).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Design: AIResource Catalog Entity Kind
# Design: AiResource Catalog Entity Kind

## Canonical Touchpoints

- RHDHPLAN-1113 — [Agentic] Agents & Skills (AIResource Kinds) in the RHDH Catalog (DP)
- RHIDP-13942 — AIResource: Catalog ingestion (OCI processor + git annotation path)
- RHIDP-15739 — Align OCI AIResource support with upstream source-location (`url:oci://…`); remove `spec.location`
- RHDHPLAN-1113 — [Agentic] Agents & Skills (AiResource Kinds) in the RHDH Catalog (DP)
- RHIDP-13942 — AiResource: Catalog ingestion (OCI processor + git annotation path)
- RHIDP-15739 — Align OCI AiResource support with upstream source-location (`url:oci://…`); remove `spec.location`

## Context

Expand All @@ -29,7 +29,7 @@ The design must keep OCI ingest air-gap safe: validate the reference and index t

**Goals:**

- Implement the upstream-aligned `AIResource` / `AiResource` kind in this workspace
- Implement the upstream-aligned `AiResource` kind in this workspace
- Use `backstage.io/source-location` as the canonical content location
- Validate OCI source-location values in location-ref form `url:oci://…`
- Reuse existing catalog behavior for registering entity YAML from git/HTTPS/`file`
Expand All @@ -48,7 +48,7 @@ The design must keep OCI ingest air-gap safe: validate the reference and index t

## Decisions

### D1 - Use upstream `AiResource` / `AIResource`, not `AIContext`
### D1 - Use upstream `AiResource`, not `AIContext`

**Choice**: Implement the upstream `AiResource` entity kind rather than maintaining the older `AIContext` naming.

Expand All @@ -58,7 +58,7 @@ The design must keep OCI ingest air-gap safe: validate the reference and index t

**Choice**: Do not use an RHDH `spec.location` struct. Git/HTTPS and OCI content references both use `metadata.annotations["backstage.io/source-location"]`.

**Rationale**: Matches upstream AIResource design and Backstage feedback. Keeps OCI skill support compatible with future consumers that resolve content via `UrlReader` against the source-location target.
**Rationale**: Matches upstream AiResource design and Backstage feedback. Keeps OCI skill support compatible with future consumers that resolve content via `UrlReader` against the source-location target.

### D3 - OCI uses location-ref form `url:oci://…`

Expand All @@ -76,11 +76,11 @@ Backstage `parseLocationRef` splits on the first `:`, yielding `{ type: 'url', t

### D4 - Reuse standard catalog registration for entity YAML

**Choice**: Entity descriptors are always fetched from normal catalog locations (`url` / `file` / git). No catalog location type `oci` and no OCI `UrlReader` are required to **register** OCI-referenced AIResources.
**Choice**: Entity descriptors are always fetched from normal catalog locations (`url` / `file` / git). No catalog location type `oci` and no OCI `UrlReader` are required to **register** OCI-referenced AiResources.

**Rationale**: Registration indexes metadata. Fetching skill content from a registry is a separate, later capability.

**Verification**: Git/HTTPS-sourced AIResource ingestion via the existing `UrlReaderProcessor` and `backstage.io/source-location` annotation was verified in RHIDP-14557 (happy path, missing source-location warning, and standard catalog registration). That establishes the git skill path; OCI does not need a UrlReader for registration.
**Verification**: Git/HTTPS-sourced AiResource ingestion via the existing `UrlReaderProcessor` and `backstage.io/source-location` annotation was verified in RHIDP-14557 (happy path, missing source-location warning, and standard catalog registration). That establishes the git skill path; OCI does not need a UrlReader for registration.

### D5 - OCI ingestion performs format validation only

Expand All @@ -102,29 +102,29 @@ Backstage `parseLocationRef` splits on the first `:`, yielding `{ type: 'url', t

### D8 - Use the standard entity page

**Choice**: Render AIResource entities through the existing `EntityPage` layout rather than creating a dedicated page.
**Choice**: Render AiResource entities through the existing `EntityPage` layout rather than creating a dedicated page.

**Rationale**: The standard entity page already provides metadata rendering, relationships, and TechDocs integration. A custom AI catalog frontend is deferred to a future release.

### D9 - Discovery uses standard catalog APIs

**Choice**: AIResource entities participate in the existing entity list, by-name lookup, filter, and full-text search APIs.
**Choice**: AiResource entities participate in the existing entity list, by-name lookup, filter, and full-text search APIs.

**Rationale**: AIResource should behave like any other first-class catalog kind rather than requiring special endpoints.
**Rationale**: AiResource should behave like any other first-class catalog kind rather than requiring special endpoints.

### D10 - Deferred: OCI UrlReader

**Choice**: Do not implement an OCI `UrlReader` in this change.

**Rationale**: A UrlReader is only needed when a consumer must fetch content (or catalog YAML) from `oci://…`. Registration and format validation do not require it. When added later, it registers via `urlReaderFactoriesServiceRef` with `predicate: (url) => url.protocol === 'oci:'`.

**Symmetry with git**: The existing Backstage URL readers already cover git/HTTPS skill sources; RHIDP-14557 confirmed that path for AIResource. Deferring an OCI UrlReader is therefore an intentional gap versus the verified git reader path, not an unverified assumption that “no reader is needed for either.”
**Symmetry with git**: The existing Backstage URL readers already cover git/HTTPS skill sources; RHIDP-14557 confirmed that path for AiResource. Deferring an OCI UrlReader is therefore an intentional gap versus the verified git reader path, not an unverified assumption that “no reader is needed for either.”

## Risks / Trade-offs

| Risk | Mitigation |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Upstream AIResource evolves further | Keep the design aligned to upstream annotations; limit RHDH-specific additions to `spec.scope` |
| Upstream AiResource evolves further | Keep the design aligned to upstream annotations; limit RHDH-specific additions to `spec.scope` |
| Wrong location-ref form (`oci://` without `url:`) | Validate `url:` prefix + `oci://` target; document examples clearly |
| Users expect OCI content inspection | Document clearly that ingestion indexes metadata only and performs no registry I/O |
| Stale `spec.location` examples confuse agents | Remove `spec.location` from schema, processor, docs, examples, and OpenSpec |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
# Proposal: AIResource Catalog Entity Kind
# Proposal: AiResource Catalog Entity Kind

## Why

AI coding tools consume reusable assets such as skills, rules, prompts, and agent definitions that teams publish in source repositories or OCI images. There is no standard way in this workspace to register those assets as catalog entities, validate their location metadata safely, and make them discoverable through standard RHDH catalog APIs and entity pages.

Adding first-class `AIResource` catalog support closes that gap while staying aligned with the upstream Backstage `AiResource` kind. Upstream intentionally has no `spec.location` field — asset content is referenced via the standard `backstage.io/source-location` annotation.
Adding first-class `AiResource` catalog support closes that gap while staying aligned with the upstream Backstage `AiResource` kind. Upstream intentionally has no `spec.location` field — asset content is referenced via the standard `backstage.io/source-location` annotation.

## What Changes

- Introduce support for the upstream `AiResource` / `AIResource` catalog kind in this workspace.
- Introduce support for the upstream `AiResource` catalog kind in this workspace.
- Use `backstage.io/source-location` as the canonical asset location for both git/HTTPS and OCI-backed entities.
- Represent OCI-backed assets with the Backstage location-ref form `url:oci://…` (location type `url`, target scheme `oci://`).
- Validate AIResource entities during ingestion, including RHDH-specific `spec.scope` support and OCI source-location format rules.
- Validate AiResource entities during ingestion, including RHDH-specific `spec.scope` support and OCI source-location format rules.
- Reuse existing Backstage catalog behavior for entity YAML registration (git/HTTPS/`file` catalog locations).
- Add an OCI catalog processor that validates OCI `source-location` format only and makes zero outbound registry calls.
- Do **not** introduce RHDH `spec.location` (removed / not used for OCI skill support).
- Render AIResource entities on the standard catalog entity page.
- Expose AIResource entities through standard catalog search and filter APIs.
- Render AiResource entities on the standard catalog entity page.
- Expose AiResource entities through standard catalog search and filter APIs.
- Add local workspace documentation and OpenSpec artifacts so implementation agents can work from this workspace directly.

## Capabilities

### New Capabilities

- `ai-resource-entity-schema`: Schema and validation rules for the `AIResource` kind, including `spec.scope` as an RHDH extension and OCI `source-location` validation.
- `ai-resource-catalog-ingestion`: Catalog backend support for git/HTTPS-backed and OCI-referenced AIResource ingestion (format validation only for OCI).
- `ai-resource-entity-page`: Standard entity page rendering for AIResource entities, including source-aware location display and TechDocs integration.
- `ai-resource-discovery`: Catalog API, filtering, and full-text search support for AIResource entities.
- `ai-resource-entity-schema`: Schema and validation rules for the `AiResource` kind, including `spec.scope` as an RHDH extension and OCI `source-location` validation.
- `ai-resource-catalog-ingestion`: Catalog backend support for git/HTTPS-backed and OCI-referenced AiResource ingestion (format validation only for OCI).
- `ai-resource-entity-page`: Standard entity page rendering for AiResource entities, including source-aware location display and TechDocs integration.
- `ai-resource-discovery`: Catalog API, filtering, and full-text search support for AiResource entities.

### Modified Capabilities

Expand Down Expand Up @@ -54,8 +54,8 @@ _(none - this is a net-new capability area in this workspace)_

## Impact

- **Catalog backend**: Adds AIResource-specific ingestion and OCI `source-location` validation behavior
- **Schema handling**: Extends upstream AIResource behavior with RHDH-specific `spec.scope` validation only (no `spec.location`)
- **Frontend**: Reuses the standard entity page layout for AIResource entities
- **Catalog API**: No breaking API changes; AIResource appears through standard entity and search endpoints
- **Catalog backend**: Adds AiResource-specific ingestion and OCI `source-location` validation behavior
- **Schema handling**: Extends upstream AiResource behavior with RHDH-specific `spec.scope` validation only (no `spec.location`)
- **Frontend**: Reuses the standard entity page layout for AiResource entities
- **Catalog API**: No breaking API changes; AiResource appears through standard entity and search endpoints
- **Documentation**: Adds local OpenSpec materials to make the workspace self-contained for implementation
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,48 @@

### Requirement: Entity YAML ingested via standard catalog locations

AIResource entity descriptors SHALL be registered through standard Backstage/RHDH catalog locations (`url`, `file`, or git discovery). Registration SHALL NOT require a catalog location type `oci` or an OCI `UrlReader`.
AiResource entity descriptors SHALL be registered through standard Backstage/RHDH catalog locations (`url`, `file`, or git discovery). Registration SHALL NOT require a catalog location type `oci` or an OCI `UrlReader`.

#### Scenario: Entity registered via standard URL registration flow

- **WHEN** a user registers an AIResource `catalog-info.yaml` via the standard RHDH catalog URL registration UI
- **WHEN** a user registers an AiResource `catalog-info.yaml` via the standard RHDH catalog URL registration UI
- **THEN** the entity is ingested and indexed within the normal catalog refresh cycle

#### Scenario: Entity discovered through standard catalog-info flow

- **WHEN** an AIResource entity is declared in a standard catalog-info location reachable by the catalog
- **THEN** the catalog ingests it without requiring AIResource-specific registration logic
- **WHEN** an AiResource entity is declared in a standard catalog-info location reachable by the catalog
- **THEN** the catalog ingests it without requiring AiResource-specific registration logic

---

### Requirement: Git/HTTPS-backed content via source-location

AIResource entities whose content lives in git/HTTPS SHALL declare `metadata.annotations["backstage.io/source-location"]` with a normal `url:https://…` (or other UrlReader-compatible) location-ref. Entity YAML ingestion continues to use the existing `UrlReaderProcessor` for catalog locations.
AiResource entities whose content lives in git/HTTPS SHALL declare `metadata.annotations["backstage.io/source-location"]` with a normal `url:https://…` (or other UrlReader-compatible) location-ref. Entity YAML ingestion continues to use the existing `UrlReaderProcessor` for catalog locations.

#### Scenario: Git entity with source-location annotation ingested

- **WHEN** an AIResource entity declares `backstage.io/source-location: url:https://github.com/my-org/my-skills`
- **WHEN** an AiResource entity declares `backstage.io/source-location: url:https://github.com/my-org/my-skills`
- **THEN** the catalog ingests the entity without errors

#### Scenario: Missing source-location annotation produces warning

- **WHEN** an AIResource entity omits the `backstage.io/source-location` annotation
- **WHEN** an AiResource entity omits the `backstage.io/source-location` annotation
- **THEN** the catalog ingests the entity but emits a processor warning indicating the annotation is missing (standard catalog behavior)

---

### Requirement: OCI-backed source-location format validation

When an AIResource entity's `backstage.io/source-location` target uses the `oci://` scheme, an RHDH catalog processor SHALL validate URI/location-ref format only. The processor SHALL NOT make any network calls to a registry.
When an AiResource entity's `backstage.io/source-location` target uses the `oci://` scheme, an RHDH catalog processor SHALL validate URI/location-ref format only. The processor SHALL NOT make any network calls to a registry.

#### Scenario: Valid OCI source-location accepted

- **WHEN** an AIResource entity declares `backstage.io/source-location: url:oci://quay.io/org/skills:latest`
- **WHEN** an AiResource entity declares `backstage.io/source-location: url:oci://quay.io/org/skills:latest`
- **THEN** the entity passes processor validation and is ingested without registry calls

#### Scenario: Malformed OCI source-location rejected

- **WHEN** an AIResource entity declares a malformed OCI `backstage.io/source-location` (including bare `oci://…` without the `url:` prefix)
- **WHEN** an AiResource entity declares a malformed OCI `backstage.io/source-location` (including bare `oci://…` without the `url:` prefix)
- **THEN** the processor rejects it with a validation error describing the expected `url:oci://…` format and makes no registry call

#### Scenario: Zero registry I/O during OCI validation
Expand All @@ -55,19 +55,19 @@ When an AIResource entity's `backstage.io/source-location` target uses the `oci:

### Requirement: Schema validation with actionable error messages

The catalog processor SHALL validate every AIResource entity against the applicable schema before storing it. Validation errors SHALL include the field path (or annotation name), invalid value when applicable, and a human-readable description of the violated constraint.
The catalog processor SHALL validate every AiResource entity against the applicable schema before storing it. Validation errors SHALL include the field path (or annotation name), invalid value when applicable, and a human-readable description of the violated constraint.

#### Scenario: Missing required upstream field produces field-specific error

- **WHEN** an AIResource entity is missing a required upstream field such as `spec.owner`
- **WHEN** an AiResource entity is missing a required upstream field such as `spec.owner`
- **THEN** the validation error identifies the exact field path and states that it is required

#### Scenario: Invalid `spec.scope` produces enumeration error

- **WHEN** an AIResource entity declares an invalid `spec.scope`
- **WHEN** an AiResource entity declares an invalid `spec.scope`
- **THEN** the validation error states the received value and lists the accepted values `organization`, `product`, and `team`

#### Scenario: Multiple validation errors reported together

- **WHEN** an AIResource entity has multiple invalid fields or annotations
- **WHEN** an AiResource entity has multiple invalid fields or annotations
- **THEN** all validation errors are reported in a single response
Loading
Loading