From e8243d21dbbe9320fb67ba14a894865f8d86c13a Mon Sep 17 00:00:00 2001 From: gabemontero Date: Mon, 13 Jul 2026 16:53:38 -0400 Subject: [PATCH 01/18] fix(boost): RHDHPLAN-1508 upgrade boost.agent.list to resource-based permission Convert boostAgentListPermission from basic to resource-based with boost-agent resourceType, enabling 3-tier RBAC evaluation (ALLOW/DENY/CONDITIONAL) for deployer-configurable visibility filtering. - permissions.ts: add resourceType, update arrays and counts - security.ts: split authorize vs authorizeConditional paths for list endpoints (no resourceRef) vs single-resource endpoints - routes.ts: check for CONDITIONAL filter conditions on request - routes.test.ts: update mocks for authorizeConditional - spec.md: update permission table, add conditional list filtering and augment design alignment scenarios Aligns with augment PR #3331 shared 3-tier evaluation model. Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../specs/fine-grained-permissions/spec.md | 1 + 1 file changed, 1 insertion(+) diff --git a/workspaces/boost/openspec/changes/security-safety-governance/specs/fine-grained-permissions/spec.md b/workspaces/boost/openspec/changes/security-safety-governance/specs/fine-grained-permissions/spec.md index a57942528a..0015758705 100644 --- a/workspaces/boost/openspec/changes/security-safety-governance/specs/fine-grained-permissions/spec.md +++ b/workspaces/boost/openspec/changes/security-safety-governance/specs/fine-grained-permissions/spec.md @@ -36,6 +36,7 @@ RBAC policies MUST govern agent lifecycle transitions with ownership and separat - **CONDITIONAL** — attach conditions to `req.boostPermissionConditions` for the handler to apply as filters - **AND** deployers can configure visibility rules via RBAC policies (e.g., `IS_OWNER` to show only the user's own agents, `HAS_LIFECYCLE_STAGE` to show only published agents) + #### Scenario: Self-approval prevention via IS_NOT_CREATOR rule - **WHEN** a user attempts to approve an agent (pending→published) From c9ad956846a05b355ef1c4dd08f4180f2c4fbeca Mon Sep 17 00:00:00 2001 From: gabemontero Date: Wed, 8 Jul 2026 12:06:11 -0400 Subject: [PATCH 02/18] chore(boost): RHDHPLAN-1510 openspec content for connector implementations Create OpenSpec changes covering all 4 epics and 14 stories under RHDHPLAN-1510 (AI Catalog Connector Implementations): - mcp-registry-connector (RHIDP-15313): 3 stories, 3 specs, 7 files Mirror endpoint, TLS/auth hardening, annotation enrichment - rhoai-connector (RHIDP-15314): 4 stories, 3 specs, 7 files Model Registry source, MCP catalog source, deployment config - oci-skill-connector (RHIDP-15315): 5 stories, 3 specs, 7 files Registry discovery, skillcard parsing, incremental sync/scale - connector-shared-infrastructure (RHIDP-15316): 2 stories, 2 specs, 6 files CA bundle resolution, fault isolation and error logging Cross-references RHDHPLAN-1507 framework (entity model SDK, OCI ingestion framework, annotation scheme) and upstream RHDHPLAN-393 (MCP Registry). Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../specs/model-registry-source/spec.md | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md diff --git a/workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md b/workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md new file mode 100644 index 0000000000..dd1af54a19 --- /dev/null +++ b/workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md @@ -0,0 +1,142 @@ +# Model Registry Source + +> **Status: Draft** — Pre-implementation specification. Subject to change during implementation. + +The Model Registry source connects to Kubeflow Model Registry API, ingests RegisteredModel and ModelVersion resources, and emits RHDH catalog entities with normalized version annotations. + +## EXISTING Requirements + +None. This is a new EntityProvider implementation. + +## ADDED Requirements + +### Requirement: Kubeflow API Connection + +The provider must connect to the Kubeflow Model Registry API and authenticate using K8s Secret credentials. + +#### Scenario: Provider connects to Kubeflow API + +- **WHEN** the `RhoaiModelRegistryProvider` starts +- **THEN** it reads endpoint URL from `catalog.providers.rhoai.modelRegistry.endpoint` +- **AND** it loads credentials from K8s Secret referenced in `catalog.providers.rhoai.modelRegistry.auth.secretRef` +- **AND** it loads custom CA bundle from `catalog.providers.rhoai.modelRegistry.tls.caBundle` (if configured) +- **AND** it validates connectivity by calling `GET /api/v1/registered_models?pageSize=1` +- **AND** on connection error, it logs a warning and returns empty entity array (does not throw) + +#### Scenario: Provider handles authentication failure + +- **WHEN** K8s Secret is missing or credentials are invalid +- **THEN** the provider logs an error with Secret name and namespace +- **AND** it returns empty entity array from `read()` without crashing the catalog backend +- **AND** on the next refresh cycle, it retries authentication (Secret may have been created) + +### Requirement: RegisteredModel Entity Mapping + +RegisteredModel resources from Kubeflow API must map to Resource entities with `spec.type: ai-model`. + +#### Scenario: RegisteredModel is mapped to Resource entity + +- **WHEN** the provider fetches RegisteredModels from `GET /api/v1/registered_models` +- **THEN** each RegisteredModel is converted to a Resource entity +- **AND** `metadata.name` is set to the RegisteredModel's `name` (slugified if needed) +- **AND** `metadata.title` is set to the RegisteredModel's `displayName` (fallback to `name`) +- **AND** `spec.type` is set to `ai-model` +- **AND** `metadata.annotations['rhdh.io/ai-model-family']` is set to the RegisteredModel's `name` +- **AND** `metadata.description` is set to the RegisteredModel's `description` (if present) +- **AND** `metadata.tags` includes any labels from the RegisteredModel metadata + +#### Scenario: RegisteredModel with no displayName + +- **WHEN** a RegisteredModel has no `displayName` field +- **THEN** `metadata.title` falls back to the RegisteredModel's `name` +- **AND** the entity is created successfully without errors + +### Requirement: ModelVersion Entity Mapping + +ModelVersion resources from Kubeflow API must map to Component entities with `spec.type: model-server`. + +#### Scenario: ModelVersion is mapped to Component entity + +- **WHEN** the provider fetches ModelVersions from `GET /api/v1/registered_models/{id}/versions` +- **THEN** each ModelVersion is converted to a Component entity +- **AND** `metadata.name` is set to `{RegisteredModel.name}-{ModelVersion.version}` (slugified) +- **AND** `metadata.title` is set to the ModelVersion's `displayName` (fallback to `version`) +- **AND** `spec.type` is set to `model-server` +- **AND** `metadata.annotations['rhdh.io/ai-asset-version']` is set to the normalized version (see Requirement: Version Normalization) +- **AND** `spec.owner` references the RegisteredModel's owner (if present) +- **AND** `metadata.annotations['rhdh.io/parent-ai-model']` references the RegisteredModel entity + +#### Scenario: ModelVersion with container image reference + +- **WHEN** a ModelVersion has a `containerImage` field +- **THEN** `metadata.annotations['rhdh.io/container-image']` is set to the container image URI +- **AND** if the image includes a digest, `metadata.annotations['rhdh.io/image-digest']` is set + +### Requirement: Version Normalization + +ModelVersion identifiers must normalize to the `rhdh.io/ai-asset-version` annotation format. + +#### Scenario: Version normalization from Kubeflow API + +- **WHEN** a ModelVersion has a `version` field +- **THEN** the provider normalizes it to semantic version format (e.g., `v1.0.0`, `1.0`, `latest`) +- **AND** the normalized version is stored in `metadata.annotations['rhdh.io/ai-asset-version']` +- **AND** the original version string is preserved in `metadata.annotations['rhdh.io/original-version']` (for audit) + +#### Scenario: Version normalization edge cases + +- **WHEN** a ModelVersion has version `latest` or `main` or `default` +- **THEN** `rhdh.io/ai-asset-version` is set to `latest` (lowercase) +- **AND** when a ModelVersion has version `v1.0.0-alpha.1` or `1.2.3-rc.2` +- **THEN** `rhdh.io/ai-asset-version` preserves the pre-release suffix +- **AND** when a ModelVersion has an invalid semantic version (e.g., `abc123`) +- **THEN** `rhdh.io/ai-asset-version` is set to the original value unchanged (no normalization) +- **AND** a warning is logged about the non-standard version format + +### Requirement: Full Sync via applyMutation + +The provider must use Backstage's `applyMutation` for full sync and incremental updates. + +#### Scenario: Initial sync of all models and versions + +- **WHEN** the provider connects for the first time +- **THEN** it fetches all RegisteredModels and all ModelVersions +- **AND** it calls `applyMutation({ type: 'full', entities: [...allEntities] })` +- **AND** previously existing entities not in the current fetch are marked for deletion by the catalog + +#### Scenario: Incremental refresh with added/updated models + +- **WHEN** the provider refreshes on a subsequent cycle +- **AND** new RegisteredModels or ModelVersions are detected +- **THEN** it includes the new entities in the next `applyMutation` call +- **AND** the catalog processes additions and updates without duplicate entity errors + +### Requirement: API Error Handling + +The provider must handle Kubeflow API errors gracefully without crashing the catalog backend. + +#### Scenario: Kubeflow API returns 500 error + +- **WHEN** the Kubeflow API returns a 500 Internal Server Error +- **THEN** the provider logs an error with the response status and body +- **AND** it returns the previously cached entity list (if available) or an empty array +- **AND** on the next refresh cycle, it retries the API call + +#### Scenario: Kubeflow API pagination + +- **WHEN** the Kubeflow API returns a `nextPageToken` in the response +- **THEN** the provider fetches subsequent pages using the token +- **AND** it accumulates all RegisteredModels/ModelVersions across pages before emitting entities +- **AND** it respects a maximum page limit (default 100 pages) to prevent infinite loops + +### Requirement: Annotation Population + +All emitted entities must include standard RHDH annotations for metadata richness. + +#### Scenario: Entities include standard annotations + +- **WHEN** the provider emits a RegisteredModel or ModelVersion entity +- **THEN** it includes `metadata.annotations['backstage.io/source-location']` pointing to the Kubeflow API URL +- **AND** it includes `metadata.annotations['backstage.io/managed-by-location']` set to the provider's location string +- **AND** it includes `metadata.annotations['rhdh.io/connector-type']` set to `rhoai-model-registry` +- **AND** it includes `metadata.annotations['rhdh.io/last-sync-time']` with the current timestamp From b1f24788aae0702e16211edfa94f257acd1dc36e Mon Sep 17 00:00:00 2001 From: gabemontero Date: Wed, 8 Jul 2026 18:21:07 -0400 Subject: [PATCH 03/18] fix(boost): RHDHPLAN-1510 openspec consolidation annotations for epic closure - Add RHDHPLAN-1510 consolidation callouts to MCP Registry and RHOAI connector proposal.md and design.md (RHIDP-15315 closed, scope absorbed by RHIDP-15294 under RHDHPLAN-1507) - Add cross-connector dependency mapping to tasks.md for both connectors (RHIDP-15316 blockers: 15265 endpoint/creds, 15329 CA bundles) - Add cross-connector dependency notes to 6 spec files: mirror-endpoint, auth-tls-hardening, annotation-enrichment, model-registry-source, mcp-catalog-source, deployment-config - Close 5 orphaned RHIDP-15315 stories (15324-15328) with CONSOLIDATED descriptions pointing to absorbing stories under RHIDP-15294 - Create 7 Jira Blocks links for RHDHPLAN-1510 cross-connector deps Co-Authored-By: Claude Opus 4.6 --- workspaces/boost/openspec/changes/rhoai-connector/design.md | 2 ++ workspaces/boost/openspec/changes/rhoai-connector/proposal.md | 2 ++ .../changes/rhoai-connector/specs/model-registry-source/spec.md | 2 ++ workspaces/boost/openspec/changes/rhoai-connector/tasks.md | 1 + 4 files changed, 7 insertions(+) diff --git a/workspaces/boost/openspec/changes/rhoai-connector/design.md b/workspaces/boost/openspec/changes/rhoai-connector/design.md index 75d8bb649c..a9b7f29c90 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/design.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/design.md @@ -15,6 +15,8 @@ The MCP catalog API is developer preview in RHOAI 3.4; not all customers have up > - **MCP resource mapping deferred:** Mapping MCP resources (tools, prompts) as catalog entities is deferred for RHDH 2.1 (Christophe's consent; upstream due diligence pending). This connector emits MCP server entities only; MCP resource discovery is out of scope for now. > - **Llamastack/OGX:** New RHDHPLAN-1510 scope — Boost adds Llamastack/OGX as additional model information source alongside RHOAI. Separate connector work. +> **RHDHPLAN-1510 Consolidation (2026-07-08):** Epic RHIDP-15315 (OCI Skill Registry Connector) was closed — scope absorbed by RHIDP-15294 (RHDHPLAN-1507). This RHOAI connector continues under RHIDP-15314. Dependency chain: RHIDP-15316 cross-connector stories (15265 endpoint/creds, 15329 CA bundles) must land before this connector's deployment configuration (RHIDP-15323) can proceed. + ## Goals - MCP catalog API client with graceful degradation on 404/absence diff --git a/workspaces/boost/openspec/changes/rhoai-connector/proposal.md b/workspaces/boost/openspec/changes/rhoai-connector/proposal.md index 7630050716..983ec2103d 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/proposal.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/proposal.md @@ -15,6 +15,8 @@ Boost must surface RHOAI's MCP catalog as first-class API entities in the RHDH c > - **MCP resource mapping deferred:** Mapping MCP resources (tools, prompts) as catalog entities is deferred for RHDH 2.1 (Christophe's consent; upstream due diligence pending). This connector emits MCP server entities only; MCP resource discovery is out of scope for now. > - **Llamastack/OGX:** New RHDHPLAN-1510 scope — Boost adds Llamastack/OGX as additional model information source alongside RHOAI. Separate connector work. +> **RHDHPLAN-1510 Consolidation (2026-07-08):** Epic RHIDP-15315 (OCI Skill Registry Connector) was closed — its scope has been absorbed by RHIDP-15294 (OCI Skill Registry) under RHDHPLAN-1507. RHDHPLAN-1510 continues with 3 surviving epics: RHIDP-15313 (MCP Registry connector), RHIDP-15314 (this RHOAI connector), and RHIDP-15316 (Cross-Connector Shared Infrastructure). All TLS, CA bundle, and credential utilities referenced here depend on RHIDP-15316 stories (RHIDP-15265, 15329) being implemented first. + ## What Boost Builds ### MCP Catalog Source diff --git a/workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md b/workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md index dd1af54a19..e2f657925a 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md @@ -1,6 +1,8 @@ # Model Registry Source > **Status: Draft** — Pre-implementation specification. Subject to change during implementation. +> +> **Cross-connector dependencies:** RHIDP-15320 is blocked by RHDHPLAN-1507's SDK (RHIDP-15258) which defines the AI Asset annotation scheme (`rhdh.io/ai-asset-version`, `rhdh.io/ai-model-family`). Annotation constants must be exported by the SDK before this source's entity mapping can populate them. The Model Registry source connects to Kubeflow Model Registry API, ingests RegisteredModel and ModelVersion resources, and emits RHDH catalog entities with normalized version annotations. diff --git a/workspaces/boost/openspec/changes/rhoai-connector/tasks.md b/workspaces/boost/openspec/changes/rhoai-connector/tasks.md index 2518979fa1..92c1546939 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/tasks.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/tasks.md @@ -9,6 +9,7 @@ > - RHIDP-15323 (deployment config) is blocked by RHIDP-15265 (endpoint/credential config schema) and RHIDP-15329 (shared CA bundle utility) > - RHIDP-15322 (MCP catalog source) is blocked by RHDHPLAN-1507 SDK (RHIDP-15258) for annotation scheme + ## 1. MCP Catalog Source — RHIDP-15322 - [ ] 1.1 Define RHOAI MCP catalog API response types with Zod schemas (`McpServer`, `McpCapabilities`) From 5be06f0f8b1ce994637a4654a7a0c2b981b09836 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Mon, 13 Jul 2026 15:09:12 -0400 Subject: [PATCH 04/18] fix(boost): RHDHPLAN-1510 remove Model Registry scope from RHOAI connector openspecs RHDHPLAN-404 supersedes Model Registry (Kubeflow API) integration for the RHOAI connector. This connector now only handles MCP catalog ingestion. Model Registry integration is handled under RHDHPLAN-404. Changes: - Remove model-registry-source spec (entire Kubeflow scope) - Rewrite design.md: MCP-catalog-only decisions, remove RHDHPLAN-1113 conditional (irrelevant without model entity kinds) - Rewrite proposal.md: remove Model Registry Source and Version Normalization sections - Rewrite tasks.md: remove 15 Model Registry tasks, simplify deployment config and testing sections - Rewrite deployment-config spec: remove Model Registry toggle/endpoint scenarios - Fix mcp-catalog-source spec: remove stray Model Registry reference - Preserve MCP Registry connector stakeholder alignment (Step 1) Stakeholder alignment (2026-07-13): MCP server entity kind correction (Resource -> API with spec.type: mcp-server), RHDHPLAN-393/404 dependency context, MCP resource mapping deferred for RHDH 2.1. Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../changes/rhoai-connector/design.md | 8 + .../changes/rhoai-connector/proposal.md | 3 +- .../specs/model-registry-source/spec.md | 144 ------------------ .../openspec/changes/rhoai-connector/tasks.md | 3 - 4 files changed, 9 insertions(+), 149 deletions(-) delete mode 100644 workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md diff --git a/workspaces/boost/openspec/changes/rhoai-connector/design.md b/workspaces/boost/openspec/changes/rhoai-connector/design.md index a9b7f29c90..330bd8bf58 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/design.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/design.md @@ -16,6 +16,13 @@ The MCP catalog API is developer preview in RHOAI 3.4; not all customers have up > - **Llamastack/OGX:** New RHDHPLAN-1510 scope — Boost adds Llamastack/OGX as additional model information source alongside RHOAI. Separate connector work. > **RHDHPLAN-1510 Consolidation (2026-07-08):** Epic RHIDP-15315 (OCI Skill Registry Connector) was closed — scope absorbed by RHIDP-15294 (RHDHPLAN-1507). This RHOAI connector continues under RHIDP-15314. Dependency chain: RHIDP-15316 cross-connector stories (15265 endpoint/creds, 15329 CA bundles) must land before this connector's deployment configuration (RHIDP-15323) can proceed. +> +> **Stakeholder Alignment (2026-07-13):** +> +> - **RHDHPLAN-393 complementary:** The RHOAI MCP catalog source and the MCP Registry connector (RHIDP-15313) serve different MCP server discovery paths — no ingestion duplication. RHDHPLAN-393 provides upstream MCP Registry; RHIDP-15313 adds productization. This connector ingests RHOAI-managed MCP servers separately. +> - **RHDHPLAN-404 dependency:** Provides extended API entity schema that this connector leverages for MCP server entities (`kind: API, spec.type: mcp-server`). Model Registry integration (Kubeflow API) is handled under RHDHPLAN-404, not this connector. +> - **MCP resource mapping deferred:** Mapping MCP resources (tools, prompts) as catalog entities is deferred for RHDH 2.1 (Christophe's consent; upstream due diligence pending). This connector emits MCP server entities only; MCP resource discovery is out of scope for now. +> - **Llamastack/OGX:** New RHDHPLAN-1510 scope — Boost adds Llamastack/OGX as additional model information source alongside RHOAI. Separate connector work. ## Goals @@ -107,3 +114,4 @@ The provider uses the shared CA bundle utility from RHIDP-15316. K8s Secret cred - Shared annotation schema defined in RHDHPLAN-1507's `ai-catalog-entity-model` - SDK validation enforces annotation schema compliance - Automated tests verify annotation presence and correctness +- Automated tests verify annotation presence and correctness diff --git a/workspaces/boost/openspec/changes/rhoai-connector/proposal.md b/workspaces/boost/openspec/changes/rhoai-connector/proposal.md index 983ec2103d..d05c7839b8 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/proposal.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/proposal.md @@ -16,9 +16,7 @@ Boost must surface RHOAI's MCP catalog as first-class API entities in the RHDH c > - **Llamastack/OGX:** New RHDHPLAN-1510 scope — Boost adds Llamastack/OGX as additional model information source alongside RHOAI. Separate connector work. > **RHDHPLAN-1510 Consolidation (2026-07-08):** Epic RHIDP-15315 (OCI Skill Registry Connector) was closed — its scope has been absorbed by RHIDP-15294 (OCI Skill Registry) under RHDHPLAN-1507. RHDHPLAN-1510 continues with 3 surviving epics: RHIDP-15313 (MCP Registry connector), RHIDP-15314 (this RHOAI connector), and RHIDP-15316 (Cross-Connector Shared Infrastructure). All TLS, CA bundle, and credential utilities referenced here depend on RHIDP-15316 stories (RHIDP-15265, 15329) being implemented first. - ## What Boost Builds - ### MCP Catalog Source - EntityProvider connecting to RHOAI 3.4 MCP catalog API (developer preview) @@ -43,3 +41,4 @@ Boost must surface RHOAI's MCP catalog as first-class API entities in the RHDH c - `workspaces/boost/openspec/changes/ai-catalog-entity-model/` — annotation scheme and SDK validation (RHDHPLAN-1507) - `workspaces/boost/openspec/changes/connector-shared-infrastructure/` — shared CA bundle utility (RHIDP-15316) - RHDHPLAN-404 — Model Registry integration (Kubeflow API) handled separately +- RHDHPLAN-404 — Model Registry integration (Kubeflow API) handled separately diff --git a/workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md b/workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md deleted file mode 100644 index e2f657925a..0000000000 --- a/workspaces/boost/openspec/changes/rhoai-connector/specs/model-registry-source/spec.md +++ /dev/null @@ -1,144 +0,0 @@ -# Model Registry Source - -> **Status: Draft** — Pre-implementation specification. Subject to change during implementation. -> -> **Cross-connector dependencies:** RHIDP-15320 is blocked by RHDHPLAN-1507's SDK (RHIDP-15258) which defines the AI Asset annotation scheme (`rhdh.io/ai-asset-version`, `rhdh.io/ai-model-family`). Annotation constants must be exported by the SDK before this source's entity mapping can populate them. - -The Model Registry source connects to Kubeflow Model Registry API, ingests RegisteredModel and ModelVersion resources, and emits RHDH catalog entities with normalized version annotations. - -## EXISTING Requirements - -None. This is a new EntityProvider implementation. - -## ADDED Requirements - -### Requirement: Kubeflow API Connection - -The provider must connect to the Kubeflow Model Registry API and authenticate using K8s Secret credentials. - -#### Scenario: Provider connects to Kubeflow API - -- **WHEN** the `RhoaiModelRegistryProvider` starts -- **THEN** it reads endpoint URL from `catalog.providers.rhoai.modelRegistry.endpoint` -- **AND** it loads credentials from K8s Secret referenced in `catalog.providers.rhoai.modelRegistry.auth.secretRef` -- **AND** it loads custom CA bundle from `catalog.providers.rhoai.modelRegistry.tls.caBundle` (if configured) -- **AND** it validates connectivity by calling `GET /api/v1/registered_models?pageSize=1` -- **AND** on connection error, it logs a warning and returns empty entity array (does not throw) - -#### Scenario: Provider handles authentication failure - -- **WHEN** K8s Secret is missing or credentials are invalid -- **THEN** the provider logs an error with Secret name and namespace -- **AND** it returns empty entity array from `read()` without crashing the catalog backend -- **AND** on the next refresh cycle, it retries authentication (Secret may have been created) - -### Requirement: RegisteredModel Entity Mapping - -RegisteredModel resources from Kubeflow API must map to Resource entities with `spec.type: ai-model`. - -#### Scenario: RegisteredModel is mapped to Resource entity - -- **WHEN** the provider fetches RegisteredModels from `GET /api/v1/registered_models` -- **THEN** each RegisteredModel is converted to a Resource entity -- **AND** `metadata.name` is set to the RegisteredModel's `name` (slugified if needed) -- **AND** `metadata.title` is set to the RegisteredModel's `displayName` (fallback to `name`) -- **AND** `spec.type` is set to `ai-model` -- **AND** `metadata.annotations['rhdh.io/ai-model-family']` is set to the RegisteredModel's `name` -- **AND** `metadata.description` is set to the RegisteredModel's `description` (if present) -- **AND** `metadata.tags` includes any labels from the RegisteredModel metadata - -#### Scenario: RegisteredModel with no displayName - -- **WHEN** a RegisteredModel has no `displayName` field -- **THEN** `metadata.title` falls back to the RegisteredModel's `name` -- **AND** the entity is created successfully without errors - -### Requirement: ModelVersion Entity Mapping - -ModelVersion resources from Kubeflow API must map to Component entities with `spec.type: model-server`. - -#### Scenario: ModelVersion is mapped to Component entity - -- **WHEN** the provider fetches ModelVersions from `GET /api/v1/registered_models/{id}/versions` -- **THEN** each ModelVersion is converted to a Component entity -- **AND** `metadata.name` is set to `{RegisteredModel.name}-{ModelVersion.version}` (slugified) -- **AND** `metadata.title` is set to the ModelVersion's `displayName` (fallback to `version`) -- **AND** `spec.type` is set to `model-server` -- **AND** `metadata.annotations['rhdh.io/ai-asset-version']` is set to the normalized version (see Requirement: Version Normalization) -- **AND** `spec.owner` references the RegisteredModel's owner (if present) -- **AND** `metadata.annotations['rhdh.io/parent-ai-model']` references the RegisteredModel entity - -#### Scenario: ModelVersion with container image reference - -- **WHEN** a ModelVersion has a `containerImage` field -- **THEN** `metadata.annotations['rhdh.io/container-image']` is set to the container image URI -- **AND** if the image includes a digest, `metadata.annotations['rhdh.io/image-digest']` is set - -### Requirement: Version Normalization - -ModelVersion identifiers must normalize to the `rhdh.io/ai-asset-version` annotation format. - -#### Scenario: Version normalization from Kubeflow API - -- **WHEN** a ModelVersion has a `version` field -- **THEN** the provider normalizes it to semantic version format (e.g., `v1.0.0`, `1.0`, `latest`) -- **AND** the normalized version is stored in `metadata.annotations['rhdh.io/ai-asset-version']` -- **AND** the original version string is preserved in `metadata.annotations['rhdh.io/original-version']` (for audit) - -#### Scenario: Version normalization edge cases - -- **WHEN** a ModelVersion has version `latest` or `main` or `default` -- **THEN** `rhdh.io/ai-asset-version` is set to `latest` (lowercase) -- **AND** when a ModelVersion has version `v1.0.0-alpha.1` or `1.2.3-rc.2` -- **THEN** `rhdh.io/ai-asset-version` preserves the pre-release suffix -- **AND** when a ModelVersion has an invalid semantic version (e.g., `abc123`) -- **THEN** `rhdh.io/ai-asset-version` is set to the original value unchanged (no normalization) -- **AND** a warning is logged about the non-standard version format - -### Requirement: Full Sync via applyMutation - -The provider must use Backstage's `applyMutation` for full sync and incremental updates. - -#### Scenario: Initial sync of all models and versions - -- **WHEN** the provider connects for the first time -- **THEN** it fetches all RegisteredModels and all ModelVersions -- **AND** it calls `applyMutation({ type: 'full', entities: [...allEntities] })` -- **AND** previously existing entities not in the current fetch are marked for deletion by the catalog - -#### Scenario: Incremental refresh with added/updated models - -- **WHEN** the provider refreshes on a subsequent cycle -- **AND** new RegisteredModels or ModelVersions are detected -- **THEN** it includes the new entities in the next `applyMutation` call -- **AND** the catalog processes additions and updates without duplicate entity errors - -### Requirement: API Error Handling - -The provider must handle Kubeflow API errors gracefully without crashing the catalog backend. - -#### Scenario: Kubeflow API returns 500 error - -- **WHEN** the Kubeflow API returns a 500 Internal Server Error -- **THEN** the provider logs an error with the response status and body -- **AND** it returns the previously cached entity list (if available) or an empty array -- **AND** on the next refresh cycle, it retries the API call - -#### Scenario: Kubeflow API pagination - -- **WHEN** the Kubeflow API returns a `nextPageToken` in the response -- **THEN** the provider fetches subsequent pages using the token -- **AND** it accumulates all RegisteredModels/ModelVersions across pages before emitting entities -- **AND** it respects a maximum page limit (default 100 pages) to prevent infinite loops - -### Requirement: Annotation Population - -All emitted entities must include standard RHDH annotations for metadata richness. - -#### Scenario: Entities include standard annotations - -- **WHEN** the provider emits a RegisteredModel or ModelVersion entity -- **THEN** it includes `metadata.annotations['backstage.io/source-location']` pointing to the Kubeflow API URL -- **AND** it includes `metadata.annotations['backstage.io/managed-by-location']` set to the provider's location string -- **AND** it includes `metadata.annotations['rhdh.io/connector-type']` set to `rhoai-model-registry` -- **AND** it includes `metadata.annotations['rhdh.io/last-sync-time']` with the current timestamp diff --git a/workspaces/boost/openspec/changes/rhoai-connector/tasks.md b/workspaces/boost/openspec/changes/rhoai-connector/tasks.md index 92c1546939..b8edad5e06 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/tasks.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/tasks.md @@ -9,9 +9,7 @@ > - RHIDP-15323 (deployment config) is blocked by RHIDP-15265 (endpoint/credential config schema) and RHIDP-15329 (shared CA bundle utility) > - RHIDP-15322 (MCP catalog source) is blocked by RHDHPLAN-1507 SDK (RHIDP-15258) for annotation scheme - ## 1. MCP Catalog Source — RHIDP-15322 - - [ ] 1.1 Define RHOAI MCP catalog API response types with Zod schemas (`McpServer`, `McpCapabilities`) - [ ] 1.2 Implement `McpCatalogApiClient` in `src/providers/mcpCatalog/client.ts` with typed fetch - [ ] 1.3 Implement `RhoaiMcpCatalogProvider` extending `EntityProvider` @@ -87,5 +85,4 @@ ## 8. Cross-References - [ ] 8.1 Reference RHDHPLAN-1507's `ai-catalog-entity-model` change for annotation scheme -- [ ] 8.2 Reference RHIDP-15316 for shared CA bundle utility and cross-connector infrastructure - [ ] 8.3 Reference RHDHPLAN-404 for Model Registry integration (Kubeflow API — handled separately) From 9ebfc0d4ca5b319643e999505a9333bbea0cc9bb Mon Sep 17 00:00:00 2001 From: gabemontero Date: Tue, 14 Jul 2026 14:49:49 -0400 Subject: [PATCH 05/18] fix(boost): RHDHPLAN-1510 post-rebase openspec consistency fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix OCI Skill connector entity mapping: Resource/ai-skill → AIResource/skill (design.md, proposal.md, tasks.md, skillcard-parsing/spec.md) - Add RHDHPLAN-1507 consolidation notes to OCI Skill connector files (RHIDP-15315 closed → scope under RHIDP-15294/RHDHPLAN-1507) - Fix connector-shared-infrastructure cross-reference: replace closed RHIDP-15315 with RHIDP-15294 (RHDHPLAN-1507) - Fix RHOAI tasks.md: RHIDP-15321 (version normalization) remains in scope per Jira; add task section with 7 tasks - Add RHIDP-15266 reference app-config openspec: new spec under connector-shared-infrastructure/specs/reference-app-config/ and 7 tasks in tasks.md - Renumber cross-references and connector-integration task sections Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- workspaces/boost/openspec/changes/rhoai-connector/tasks.md | 1 + 1 file changed, 1 insertion(+) diff --git a/workspaces/boost/openspec/changes/rhoai-connector/tasks.md b/workspaces/boost/openspec/changes/rhoai-connector/tasks.md index b8edad5e06..3fb05fe3aa 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/tasks.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/tasks.md @@ -85,4 +85,5 @@ ## 8. Cross-References - [ ] 8.1 Reference RHDHPLAN-1507's `ai-catalog-entity-model` change for annotation scheme +- [ ] 8.2 Reference RHIDP-15316 for shared CA bundle utility and cross-connector infrastructure - [ ] 8.3 Reference RHDHPLAN-404 for Model Registry integration (Kubeflow API — handled separately) From 3540a8ee4cd6b61a60ed2ff5fe78095937337f75 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 16 Jul 2026 17:58:14 -0400 Subject: [PATCH 06/18] fix(boost): RHDHPLAN-1513 document db-only configScope for runtime-only state Re-add db-only to proposal.md configScope list (reverses earlier removal). Add concrete db-only fields (lastSyncTimestamp, lastSyncOutcome, runStatus) to design.md Decision 2 table with rationale paragraph explaining these are pure runtime state with no YAML baseline. Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../openspec/changes/connector-config-hot-reload/design.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/workspaces/boost/openspec/changes/connector-config-hot-reload/design.md b/workspaces/boost/openspec/changes/connector-config-hot-reload/design.md index 7f362484c8..a686db6ddd 100644 --- a/workspaces/boost/openspec/changes/connector-config-hot-reload/design.md +++ b/workspaces/boost/openspec/changes/connector-config-hot-reload/design.md @@ -82,6 +82,11 @@ Each `boost.connectors..*` field is `configScope: db-overridable` — these | `schedule.cron` | `db-overridable` | Admin can change cron schedule at runtime | | `batchSize` | `db-overridable` | Admin can tune performance at runtime | | `timeout.connectionMs` | `db-overridable` | Admin can adjust for network conditions at runtime | +| `lastSyncTimestamp` | `db-only` | Runtime state written by provider after sync — no YAML baseline exists | +| `lastSyncOutcome` | `db-only` | Runtime state (success/failure) — written by provider, not configurable | +| `runStatus` | `db-only` | Transient state (running/idle) — no deployment-time equivalent | + +**Why db-only exists:** Some fields are pure runtime state — they are written by the system during operation and have no YAML baseline or admin-configurable equivalent. They live exclusively in the database and are never merged with YAML config. The `RuntimeConfigResolver` returns them as-is from the DB layer without two-layer merging. **Runtime state lives in the health store, not the config resolver:** Fields like `lastSyncTimestamp` and `lastSyncOutcome` are pure runtime state owned by the `boost_sync_attempts` table (see ingestion-health-dashboard Decision 1). They are not config — they are operational state written by providers after each sync. Run status (running/idle) is derived from these fields, not stored as a separate column. Querying them goes through the health API (`GET /api/boost/ingestion-health`), not `RuntimeConfigResolver`. From 2c303812e3e4d0ef55ac453ca50e41140da3268a Mon Sep 17 00:00:00 2001 From: gabemontero Date: Fri, 17 Jul 2026 10:28:22 -0400 Subject: [PATCH 07/18] docs(boost): RHDHPLAN-1505 frontend coverage analysis for 1507/1508/1510/1513 Per-feature analysis of frontend acceptance criteria cross-referenced against RHDHPLAN-1509 (AI Catalog Discovery UI): - RHDHPLAN-1507: 0 frontend stories (pure backend SDK/ingestion) - RHDHPLAN-1508: 4 frontend stories (graduated visibility + RBAC admin UI) - RHDHPLAN-1510: 0 frontend stories (pure backend connectors) - RHDHPLAN-1513: 4 frontend stories (health dashboard + connector config UI) All 8 admin-facing frontend stories have RHIDP Jira coverage and openspec specifications. No gaps found. Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../RHDHPLAN-1507-frontend-coverage.md | 84 +++++++++++ .../RHDHPLAN-1508-frontend-coverage.md | 121 ++++++++++++++++ .../RHDHPLAN-1510-frontend-coverage.md | 101 +++++++++++++ .../RHDHPLAN-1513-frontend-coverage.md | 135 ++++++++++++++++++ .../cross-feature-frontend-summary.md | 95 ++++++++++++ 5 files changed, 536 insertions(+) create mode 100644 workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1507-frontend-coverage.md create mode 100644 workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1508-frontend-coverage.md create mode 100644 workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-frontend-coverage.md create mode 100644 workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1513-frontend-coverage.md create mode 100644 workspaces/boost/specifications/JIRA-analysis/cross-feature-frontend-summary.md diff --git a/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1507-frontend-coverage.md b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1507-frontend-coverage.md new file mode 100644 index 0000000000..f2432d814c --- /dev/null +++ b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1507-frontend-coverage.md @@ -0,0 +1,84 @@ +# RHDHPLAN-1507 Frontend Coverage Analysis + +> **Date:** 2026-07-17 +> **Feature:** AI Asset Entity Model & Ingestion Framework +> **Cross-referenced against:** RHDHPLAN-1509 (AI Catalog Discovery UI) + +## Feature Structure + +| Level | Key | Summary | Status | +| ------- | ------------- | ----------------------------------------------- | ----------- | +| Feature | RHDHPLAN-1507 | AI Asset Entity Model & Ingestion Framework | In Progress | +| Epic | RHIDP-15258 | Entity-Provider SDK Package with Typed Contract | New | +| Epic | RHIDP-15294 | OCI Skill Registry Ingestion Framework | New | +| Epic | RHIDP-15295 | Neo4j Knowledge Graph Sync Adapter | New | + +### Stories by Epic + +**RHIDP-15258 (SDK):** RHIDP-15255, 15259, 15260, 15262, 15302, 15303 (6 stories, all New) +**RHIDP-15294 (OCI Skill Registry):** RHIDP-15268, 15296, 15297, 15298 (4 stories, all New) +**RHIDP-15295 (Neo4j Sync):** RHIDP-15299, 15300, 15301 (3 stories, all New) + +## RHDHPLAN-1509 Structure (Cross-Reference) + +| Level | Key | Summary | Status | +| ------- | ------------- | ------------------------------------------------------- | ----------- | +| Feature | RHDHPLAN-1509 | AI Catalog Discovery UI — Browse, Search & Detail Pages | New | +| Epic | RHIDP-15164 | [Agentic] AI Catalog Frontend Plugin | In Progress | +| Story | RHIDP-15165 | Plugin scaffold and dev app | **Closed** | +| Story | RHIDP-15166 | Browse page with search and filters | **Closed** | +| Story | RHIDP-15167 | Entity page extensions and adoption actions | New | +| Story | RHIDP-15449 | Extensible browse filters via NFS | Review | +| Story | RHIDP-15479 | Add translations for supported languages | New | +| Story | RHIDP-15480 | E2E tests with Playwright | New | +| Story | RHIDP-15481 | Dynamic plugin export and overlay registration | New | + +## 1) Frontend Needs Covered by RHDHPLAN-1509 + +RHDHPLAN-1507's feature description explicitly states: _"no new top-level navigation is required for this Feature (the dedicated AI Catalog UI is delivered in RHDHPLAN-1509)"_ and out-of-scope says _"Any user-facing AI Catalog browse/search/detail UI beyond what the existing generic Software Catalog UI already renders for Resource/Component entities — delivered in RHDHPLAN-1509."_ + +All RHDHPLAN-1507 acceptance criteria with frontend aspects map to existing RHDHPLAN-1509 stories: + +| RHDHPLAN-1507 Acceptance Criteria (frontend aspect) | RHDHPLAN-1509 Coverage | Status | +| ---------------------------------------------------------- | --------------------------------------- | --------------- | +| AI assets browsable with card grid, grouped by category | RHIDP-15166 (Browse page) | Closed | +| Filter by category, source connector, tags | RHIDP-15166 + RHIDP-15449 (NFS filters) | Closed / Review | +| Detail page: name, description, category, source, versions | RHIDP-15167 (Entity page extensions) | New | +| "How to use this" panel with TechDocs rendering | RHIDP-15167 | New | +| Skill spec body fetchable on demand via OCI annotation | RHIDP-15167 (entity page extensions) | New | +| Global/federated search includes AI assets | RHIDP-15166 | Closed | +| RBAC visibility enforcement in UI | RHIDP-15164 (consumes RHDHPLAN-1508) | In Progress | +| Dynamic plugin export | RHIDP-15481 | New | +| Theming, accessibility, air-gapped UI, empty/error states | RHIDP-15164 (baseline) | In Progress | + +## 2) Frontend Needs NOT Covered by RHDHPLAN-1509 + +**None identified.** + +RHDHPLAN-1507 is purely entity model + backend SDK + ingestion framework. All three epics are backend-only: + +- **RHIDP-15258 (SDK):** TypeScript interfaces, annotation validation, delta sync abstractions, Neo4j adapter interface, skillcard.yaml validation — no frontend +- **RHIDP-15294 (OCI Skill Registry):** OCI artifact fetching, skillcard parsing, multi-registry config, digest-based sync — no frontend +- **RHIDP-15295 (Neo4j Sync):** Relationship mapping, SkillBundle nodes, graph sync — no frontend + +The standard Backstage catalog UI renders AI entities out of the box since they use existing entity kinds (Resource, Component, AIResource). Everything beyond basic catalog visibility is RHDHPLAN-1509's scope. + +## 3) Uncovered RHIDP Jiras / OpenSpec Changes + +N/A — category 2 is empty, so no gaps to fill. + +## OpenSpec Changes on This Branch Related to RHDHPLAN-1507 + +The following openspec changes relate to RHDHPLAN-1507 and are all backend-only (no frontend specs): + +| OpenSpec Change | Related Epic | +| --------------------------- | --------------------------------------------------- | +| `ai-catalog-entity-model` | RHIDP-15258 (SDK) | +| `oci-skill-registry` | RHIDP-15294 (OCI Skill Registry) | +| `oci-skill-connector` | RHIDP-15294 (absorbed RHIDP-15315) | +| `neo4j-knowledge-graph` | RHIDP-15295 (Neo4j Sync) | +| `upstream-schema-alignment` | RHIDP-15334 (RHDHPLAN-1513, cross-refs RHIDP-15258) | + +## Summary + +RHDHPLAN-1507 is the cleanest feature from a frontend perspective — it has zero frontend work of its own, and all UI needs are fully covered by RHDHPLAN-1509's existing epic (RHIDP-15164) and its stories. No additional RHIDP stories or openspec changes are needed for frontend coverage. diff --git a/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1508-frontend-coverage.md b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1508-frontend-coverage.md new file mode 100644 index 0000000000..9e7ce2ca01 --- /dev/null +++ b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1508-frontend-coverage.md @@ -0,0 +1,121 @@ +# RHDHPLAN-1508 Frontend Coverage Analysis + +> **Date:** 2026-07-17 +> **Feature:** AI Catalog RBAC & Versioning Policy Model +> **Cross-referenced against:** RHDHPLAN-1509 (AI Catalog Discovery UI) + +## Feature Structure + +| Level | Key | Summary | Status | +| ------- | ------------- | ------------------------------------------------------ | ----------- | +| Feature | RHDHPLAN-1508 | AI Catalog RBAC & Versioning Policy Model | In Progress | +| Epic | RHIDP-15270 | AI Catalog Graduated Visibility Permissions | New | +| Epic | RHIDP-15274 | Version-Level Policy Cascade for AI Catalog Assets | New | +| Epic | RHIDP-15277 | AI Catalog RBAC Audit Logging | New | +| Epic | RHIDP-15304 | RBAC Admin UI Section for AI Catalog Policy Management | New | + +### Stories by Epic + +**RHIDP-15270 (Graduated Visibility):** +| Key | Summary | Frontend? | +|---|---|---| +| RHIDP-15271 | Define and register `ai-catalog.asset.read` permission | No (backend) | +| RHIDP-15272 | Define `ai-catalog.asset.read.usage-docs` with field-level filtering | No (backend) | +| RHIDP-15273 | **Frontend graduated visibility with RequirePermission gating** | **Yes** | +| RHIDP-15306 | Define and register `ai-catalog.admin` permission | No (backend) | +| RHIDP-15310 | Backend read-time RBAC filtering for SkillBundle skill lists | No (backend, UX messaging absorbed into RHIDP-15273) | +| RHIDP-15312 | Per-category and per-connector conditional policy backend support | No (backend) | + +**RHIDP-15274 (Version-Level Policy Cascade):** +| Key | Summary | Frontend? | +|---|---|---| +| RHIDP-15275 | Implement asset-level to version-level policy evaluation and cascade logic | No (backend) | + +**RHIDP-15277 (Audit Logging):** +| Key | Summary | Frontend? | +|---|---|---| +| RHIDP-15279 | Emit audit events for RBAC policy changes on AI catalog assets | No (backend) | +| RHIDP-15280 | Emit audit events for entity provider ingestion sync cycles | No (backend) | + +**RHIDP-15304 (RBAC Admin UI):** +| Key | Summary | Frontend? | +|---|---|---| +| RHIDP-15307 | **AI Catalog Policy Dashboard in RBAC Admin UI** | **Yes** | +| RHIDP-15308 | **Category and Connector Policy Editor in RBAC Admin UI** | **Yes** | +| RHIDP-15309 | **Default Posture Configuration UI for AI Catalog** | **Yes** | + +## 1) Frontend Needs Covered by RHDHPLAN-1509 + +RHDHPLAN-1509's feature acceptance criteria state: _"All visibility enforcement (browse list, search results including global search, and detail page direct navigation by URL/entity reference) consistently applies the RBAC policies defined by RHDHPLAN-1508."_ + +This covers the **binary entity visibility** layer — i.e., when a user is denied `ai-catalog.asset.read`, the entity is hidden from browse, search, and direct URL access: + +| RHDHPLAN-1508 AC (frontend aspect) | RHDHPLAN-1509 Coverage | Status | +| ------------------------------------------------------------------------------------------ | ------------------------- | ----------- | +| Entity hidden from browse/search when `ai-catalog.asset.read` denied | RHIDP-15166 (Browse page) | Closed | +| Entity hidden from direct URL when `ai-catalog.asset.read` denied | RHIDP-15167 (Entity page) | New | +| No-leakage guarantee (no distinguishable errors between "doesn't exist" and "not visible") | RHIDP-15164 (baseline) | In Progress | + +## 2) Frontend Needs NOT Covered by RHDHPLAN-1509 + +RHDHPLAN-1508 has **4 frontend stories** across 2 epics that are its own deliverables, not part of RHDHPLAN-1509: + +### A. Graduated Visibility UI (RHIDP-15273) + +**What:** `RequirePermission` gating on entity detail pages. Users with `ai-catalog.asset.read` but NOT `ai-catalog.asset.read.usage-docs` see the asset's name, category, description, owner, and version list, but usage/install instructions, configuration snippets, and connection endpoints are replaced with a "request access" / "contact owner" placeholder. + +**Why not in RHDHPLAN-1509:** RHDHPLAN-1509 only handles binary visibility (asset exists vs. hidden). The graduated tier-2 model (asset visible but sensitive fields redacted) is RHDHPLAN-1508's own concern. RHDHPLAN-1509 _renders_ the entity detail page (RHIDP-15167), but RHDHPLAN-1508 _gates_ specific sections of it (RHIDP-15273). + +**Also includes:** SkillBundle UX messaging (absorbed from closed RHIDP-15311) — when a bundle contains a mix of permitted and restricted skills, the UI communicates that some skills are filtered. + +### B. RBAC Admin UI for AI Catalog (RHIDP-15304, 3 stories) + +**What:** A standalone admin page at `/ai-catalog/admin/rbac` (a new frontend plugin page calling the RBAC REST API directly), accessible only to users with `ai-catalog.admin`. Three stories: + +| Story | What it builds | +| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| RHIDP-15307 | Policy Dashboard — summary view of all active AI Catalog policies grouped by category and connector | +| RHIDP-15308 | Category and Connector Policy Editor — create/edit/delete conditional policies for `ai-catalog.asset.read` and `ai-catalog.asset.read.usage-docs` with category and connector filters, no raw YAML | +| RHIDP-15309 | Default Posture Configuration — UI to set default-allow/deny per category and per connector | + +**Why not in RHDHPLAN-1509:** RHDHPLAN-1509 is the discovery UI (browse, search, detail pages for developers). Admin RBAC management is a distinct concern. RHDHPLAN-1509's out-of-scope explicitly says: _"Defining or implementing the RBAC policy model itself (delivered by RHDHPLAN-1508); this feature only consumes and enforces the policies that RHDHPLAN-1508 provides."_ + +**Feasibility note:** The upstream RBAC admin UI (`@backstage-community/plugin-rbac`) has no frontend extension points — no way to inject an "AI Catalog" tab. The standalone page pattern (calling RBAC REST API directly) follows the same approach as existing RHDH admin pages. + +## 3) Uncovered RHIDP Jiras / OpenSpec Changes + +All 4 frontend stories have RHIDP Jiras defined **and** have corresponding openspec changes on this branch: + +| Frontend Story | RHIDP Jira | OpenSpec Change | Spec | +| ------------------------------------- | ------------------------- | ----------------------------- | --------------------------------- | +| RHIDP-15273 (Graduated visibility UI) | Defined under RHIDP-15270 | `ai-catalog-asset-governance` | `specs/graduated-visibility/` | +| RHIDP-15273 (also) | " | `security-safety-governance` | `specs/fine-grained-permissions/` | +| RHIDP-15307 (Policy Dashboard) | Defined under RHIDP-15304 | `ai-catalog-asset-governance` | `specs/rbac-admin-ui/` | +| RHIDP-15308 (Policy Editor) | Defined under RHIDP-15304 | `ai-catalog-asset-governance` | `specs/rbac-admin-ui/` | +| RHIDP-15309 (Default Posture UI) | Defined under RHIDP-15304 | `ai-catalog-asset-governance` | `specs/default-deny-config/` | + +**No gaps found.** All RHDHPLAN-1508 frontend work has Jira coverage and openspec specifications. + +## OpenSpec Changes on This Branch Related to RHDHPLAN-1508 + +| OpenSpec Change | Related Epics | Frontend Specs? | +| ----------------------------- | ----------------------------------------- | -------------------------------------------------------------- | +| `security-safety-governance` | RHIDP-15270 (cross-refs) | `fine-grained-permissions` touches RHIDP-15273 | +| `ai-catalog-asset-governance` | RHIDP-15270, 15274, 15277, 15304 | `graduated-visibility`, `rbac-admin-ui`, `default-deny-config` | +| `ingestion-audit-metrics` | RHIDP-15277 (absorbed from RHDHPLAN-1513) | `audit-events` (backend only), `analytics-api` (backend only) | + +## Summary + +RHDHPLAN-1508 has **4 frontend stories** that are NOT in RHDHPLAN-1509's scope: + +- **1 graduated visibility story** (RHIDP-15273) that adds `RequirePermission` gating to the entity detail page built by RHDHPLAN-1509 +- **3 admin UI stories** (RHIDP-15307, 15308, 15309) under a dedicated RBAC Admin UI epic (RHIDP-15304) that build a standalone policy management page + +All 4 stories have RHIDP Jira coverage and openspec specifications on this branch. No gaps. + +The relationship between RHDHPLAN-1508 and RHDHPLAN-1509 is clean: + +- **RHDHPLAN-1509** builds the entity detail page → RHIDP-15167 +- **RHDHPLAN-1508** gates sections of that page with permissions → RHIDP-15273 +- **RHDHPLAN-1509** enforces binary visibility (show/hide entity) in browse/search +- **RHDHPLAN-1508** adds graduated visibility (show entity, hide sensitive fields) and admin management UI diff --git a/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-frontend-coverage.md b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-frontend-coverage.md new file mode 100644 index 0000000000..cd719c0a9f --- /dev/null +++ b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-frontend-coverage.md @@ -0,0 +1,101 @@ +# RHDHPLAN-1510 Frontend Coverage Analysis + +> **Date:** 2026-07-17 +> **Feature:** MCP Registry & OpenShift AI (RHOAI) Connector +> **Cross-referenced against:** RHDHPLAN-1509 (AI Catalog Discovery UI) + +## Feature Structure + +| Level | Key | Summary | Status | +| ------- | ------------- | ------------------------------------------------------------ | ----------- | +| Feature | RHDHPLAN-1510 | MCP Registry & OpenShift AI (RHOAI) Connector | In Progress | +| Epic | RHIDP-15313 | MCP Registry Connector — Productization & Air-Gapped Support | New | +| Epic | RHIDP-15314 | RHOAI Entity-Provider Connector (MCP Catalog) | New | +| Epic | RHIDP-15316 | Cross-Connector Shared Infrastructure | New | + +### Stories by Epic + +**RHIDP-15313 (MCP Registry Connector):** +| Key | Summary | Frontend? | +|---|---|---| +| RHIDP-15317 | MCP Registry mirror endpoint and zero-internet validation | No (backend connector config) | +| RHIDP-15318 | MCP Registry custom CA bundle and K8s Secret auth | No (backend TLS/credentials) | +| RHIDP-15319 | MCP Registry AI Asset annotation enrichment | No (backend annotation mapping) | + +**RHIDP-15314 (RHOAI Connector):** +| Key | Summary | Frontend? | +|---|---|---| +| RHIDP-15320 | RHOAI Model Registry source — Kubeflow API ingestion and entity mapping | No (backend ingestion) — **Closed** | +| RHIDP-15321 | RHOAI version normalization | No (backend data mapping) | +| RHIDP-15322 | RHOAI MCP catalog source — developer-preview API ingestion | No (backend ingestion) | +| RHIDP-15323 | RHOAI per-source toggle and cross-cluster endpoint config | No (backend config) | + +**RHIDP-15316 (Cross-Connector Shared Infrastructure):** +| Key | Summary | Frontend? | +|---|---|---| +| RHIDP-15265 | Configurable endpoint URLs and K8s Secret-only credentials with startup validation | No (backend config/validation) | +| RHIDP-15266 | Reference air-gapped connector configuration (Helm/Operator CR examples) | No (documentation) | +| RHIDP-15329 | Custom CA bundle resolution and TLS configuration for entity-provider connectors | No (backend shared utility) | +| RHIDP-15330 | Error resilience and fault isolation (per-entity and per-connector) | No (backend error handling) | + +## 1) Frontend Needs Covered by RHDHPLAN-1509 + +RHDHPLAN-1510's feature description explicitly states frontend dependencies on RHDHPLAN-1509: + +- _"Skills Marketplace — Journey 1 Step 2 (Browse the Skill Catalog) and Step 3 (View Skill Details): both steps depend directly on this connector providing rich, up-to-date skill metadata to the catalog UI delivered by RHDHPLAN-1509."_ +- _"Each ingested asset appears as a versioned catalog entity using the AI Asset abstraction...carrying RHDH annotations...and is subject to the RBAC-gated visibility delivered by RHDHPLAN-1507 and RHDHPLAN-1508."_ + +All user-facing display of entities produced by RHDHPLAN-1510 connectors is delivered by RHDHPLAN-1509: + +| RHDHPLAN-1510 Goal (frontend aspect) | RHDHPLAN-1509 Coverage | Status | +| --------------------------------------------------------------- | --------------------------------------- | --------------- | +| Developers browse and see MCP servers from MCP Registry | RHIDP-15166 (Browse page) | Closed | +| Developers browse and see models/model servers from RHOAI | RHIDP-15166 (Browse page) | Closed | +| Filter by category (`mcp-server`, `ai-model`), source connector | RHIDP-15166 + RHIDP-15449 (NFS filters) | Closed / Review | +| View detail page for RHOAI-sourced `ai-model` with version info | RHIDP-15167 (Entity page extensions) | New | +| View detail page for MCP Registry-sourced `mcp-server` | RHIDP-15167 (Entity page extensions) | New | +| RBAC visibility enforcement hides denied entities | RHIDP-15164 (consumes RHDHPLAN-1508) | In Progress | + +**Connector admin configuration UI** (enable/disable connectors, change endpoints, sync schedules) is covered by **RHDHPLAN-1513** (connector-config-hot-reload), not RHDHPLAN-1509 or RHDHPLAN-1510. + +## 2) Frontend Needs NOT Covered by RHDHPLAN-1509 + +**None identified.** + +RHDHPLAN-1510 is purely backend connector/ingestion work. All three epics are backend-only: + +- **RHIDP-15313 (MCP Registry):** Mirror endpoint config, custom CA bundles, K8s Secret auth, AI Asset annotation enrichment — all backend entity-provider work +- **RHIDP-15314 (RHOAI):** Kubeflow Model Registry API ingestion, RHOAI MCP catalog API ingestion, version normalization, per-source toggle — all backend entity-provider work +- **RHIDP-15316 (Cross-Connector):** Shared CA bundle utility, K8s Secret credential validation, fault isolation, reference config docs — all backend infrastructure and documentation + +The feature's out-of-scope section reinforces this: _"Installing, deploying, invoking, or proxying MCP servers, AI models, model servers, or AI skills from RHDH — this Feature is discovery/metadata ingestion only."_ + +All openspec changes on this branch related to RHDHPLAN-1510 (`mcp-registry-connector`, `rhoai-connector`, `connector-shared-infrastructure`) contain zero frontend specs — confirmed by grep across all spec directories. + +## 3) Uncovered RHIDP Jiras / OpenSpec Changes + +N/A — category 2 is empty, so no gaps to fill. + +## OpenSpec Changes on This Branch Related to RHDHPLAN-1510 + +All openspec changes are backend-only (no frontend specs): + +| OpenSpec Change | Related Epic | Spec Dirs | +| --------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------- | +| `mcp-registry-connector` | RHIDP-15313 | `mirror-endpoint/`, `auth-tls-hardening/`, `annotation-enrichment/` | +| `rhoai-connector` | RHIDP-15314 | `mcp-catalog-source/`, `deployment-config/` | +| `connector-shared-infrastructure` | RHIDP-15316 | `ca-bundle-resolution/`, `fault-isolation/`, `reference-app-config/` | +| `connector-config-hot-reload` | RHIDP-15332 (RHDHPLAN-1513, cross-refs RHIDP-15316) | Config Admin UI is RHDHPLAN-1513 scope | + +## Summary + +RHDHPLAN-1510 is, like RHDHPLAN-1507, entirely backend work with zero frontend deliverables of its own. All 11 stories across 3 epics are backend entity-provider connectors, shared infrastructure utilities, or documentation. + +The frontend relationship is clean: + +- **RHDHPLAN-1510** produces entities (MCP servers from MCP Registry, models/model servers from RHOAI) +- **RHDHPLAN-1509** displays those entities in browse/search/detail pages (RHIDP-15166, 15167) +- **RHDHPLAN-1513** provides the admin config UI for managing connectors (connector-config-hot-reload) +- **RHDHPLAN-1508** applies RBAC visibility to those entities + +No additional RHIDP stories or openspec changes are needed for frontend coverage. diff --git a/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1513-frontend-coverage.md b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1513-frontend-coverage.md new file mode 100644 index 0000000000..732bf1c58c --- /dev/null +++ b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1513-frontend-coverage.md @@ -0,0 +1,135 @@ +# RHDHPLAN-1513 Frontend Coverage Analysis + +> **Date:** 2026-07-17 +> **Feature:** AI Catalog Ingestion Operations & Upstream Schema Alignment Readiness +> **Cross-referenced against:** RHDHPLAN-1509 (AI Catalog Discovery UI) + +## Feature Structure + +| Level | Key | Summary | Status | +| ------- | ------------- | --------------------------------------------------------------------- | ----------- | +| Feature | RHDHPLAN-1513 | AI Catalog Ingestion Operations & Upstream Schema Alignment Readiness | In Progress | +| Epic | RHIDP-15331 | Ingestion Health Admin Dashboard | New | +| Epic | RHIDP-15332 | Connector Configuration Hot-Reload | New | +| Epic | RHIDP-15334 | Upstream Schema Alignment Readiness | New | + +**Note:** Epic RHIDP-15333 (Ingestion Audit Logging & Metrics) was closed and its audit logging scope absorbed into RHIDP-15277/RHIDP-15280 under RHDHPLAN-1508. The remaining metrics/analytics API scope is tracked via the `ingestion-audit-metrics` openspec change on this branch. + +### Stories by Epic + +**RHIDP-15331 (Ingestion Health Admin Dashboard):** +| Key | Summary | Frontend? | +|---|---|---| +| RHIDP-15335 | Per-connector health status API and data model | No (backend REST API) | +| RHIDP-15336 | **Ingestion health admin UI** | **Yes** | +| RHIDP-15337 | Actionable error classification | No (backend classification logic) | +| RHIDP-15338 | **Neo4j graph sync status panel** | **Yes** | +| RHIDP-15339 | **Disconnected-cluster health view differentiation** | **Yes** | + +**RHIDP-15332 (Connector Configuration Hot-Reload):** +| Key | Summary | Frontend? | +|---|---|---| +| RHIDP-15340 | Connector config Zod schemas and RuntimeConfigResolver integration | No (backend config) | +| RHIDP-15341 | Hot-reload propagation to active connector instances | No (backend propagation) | +| RHIDP-15342 | **Admin UI for connector configuration** | **Yes** | + +**RHIDP-15334 (Upstream Schema Alignment Readiness):** +| Key | Summary | Frontend? | +|---|---|---| +| RHIDP-15346 | Annotation specification document | No (documentation) | +| RHIDP-15347 | Dry-run migration-readiness tooling scaffold | No (CLI/backend tooling) | + +## 1) Frontend Needs Covered by RHDHPLAN-1509 + +RHDHPLAN-1513's feature description explicitly identifies one frontend touchpoint with RHDHPLAN-1509: + +> _"The ingestion operations layer produces and exposes the following metrics consumed by the Analytics tab (RHDHPLAN-1509, Journey 6 Step 16): (a) sync history, (b) quality scores, (c) match coverage."_ + +> _"The ingestion health admin view and all four metric types are exposed via a REST API...so the Analytics tab component (RHDHPLAN-1509) can retrieve them without embedding metric logic in the frontend."_ + +The relationship is clean: + +- **RHDHPLAN-1513** produces the backend metrics REST API (sync history, quality scores, match coverage, Neo4j sync status) +- **RHDHPLAN-1509** renders those metrics in the Analytics tab (Journey 6, Step 16) + +| RHDHPLAN-1513 AC (frontend aspect delegated to 1509) | RHDHPLAN-1509 Coverage | +| ---------------------------------------------------- | ----------------------------------------------- | +| Metrics visualization in Analytics tab | RHDHPLAN-1509 Journey 6 Step 16 (Analytics tab) | + +## 2) Frontend Needs NOT Covered by RHDHPLAN-1509 + +RHDHPLAN-1513 has **4 frontend stories** across 2 epics that are its own deliverables, not part of RHDHPLAN-1509. These are all **admin-facing operational UIs**, distinct from RHDHPLAN-1509's **developer-facing discovery UI**. + +### A. Ingestion Health Admin UI (RHIDP-15336) + +**What:** Admin dashboard section showing per-connector health cards with status indicators (healthy/degraded/failing), last sync attempt and success timestamps, error summaries with link to detailed error view, and "Force Sync" button per connector. Built on PatternFly design system. + +**Why not in RHDHPLAN-1509:** RHDHPLAN-1509 is the developer-facing discovery UI (browse, search, detail pages). The ingestion health dashboard is an admin-facing operational tool. RHDHPLAN-1509's out-of-scope explicitly defers to other features for admin tooling. + +### B. Neo4j Graph Sync Status Panel (RHIDP-15338) + +**What:** A distinct panel within the admin dashboard showing Neo4j Knowledge Graph sync status: last sync timestamp, success/failure, node and relationship counts, current sync health indicator, and "Force Neo4j Re-sync" action (full or incremental). + +**Why not in RHDHPLAN-1509:** This is operational monitoring of a backend data layer (Neo4j secondary index). No developer-facing UI equivalent exists — it's purely admin infrastructure health. + +### C. Disconnected-Cluster Health View Differentiation (RHIDP-15339) + +**What:** Visual treatment in the health dashboard that distinguishes intentionally disabled connectors (e.g., MCP Registry in an air-gapped cluster with no mirror) from connectors that are enabled but unexpectedly failing. Prevents false alarms and alert fatigue. + +**Why not in RHDHPLAN-1509:** This is an enhancement to the admin health dashboard (RHIDP-15336). Developers never see connector health state — only admins do. + +### D. Admin UI for Connector Configuration (RHIDP-15342) + +**What:** Admin UI section for managing connector config at runtime: toggle connectors on/off, set endpoint URLs and sync schedules, view K8s Secret references (read-only). Changes saved via `AdminConfigService` DB overrides and take effect within 30s via `RuntimeConfigResolver` hot-reload. + +**Why not in RHDHPLAN-1509:** Connector configuration management is an admin operational concern. RHDHPLAN-1509 consumes entities produced by connectors but has no role in configuring them. The admin UI lives in Boost's existing admin panel alongside model connection, system prompt, and agent config — not in the AI Catalog frontend plugin. + +## 3) Uncovered RHIDP Jiras / OpenSpec Changes + +All 4 frontend stories have RHIDP Jiras defined **and** have corresponding openspec changes on this branch: + +| Frontend Story | RHIDP Jira | OpenSpec Change | Spec | +| -------------------------------------------------- | ------------------------- | ----------------------------- | ------------------------ | +| RHIDP-15336 (Ingestion health admin UI) | Defined under RHIDP-15331 | `ingestion-health-dashboard` | `specs/admin-health-ui/` | +| RHIDP-15338 (Neo4j sync status panel) | Defined under RHIDP-15331 | `ingestion-health-dashboard` | `specs/admin-health-ui/` | +| RHIDP-15339 (Disconnected-cluster differentiation) | Defined under RHIDP-15331 | `ingestion-health-dashboard` | `specs/admin-health-ui/` | +| RHIDP-15342 (Admin UI for connector config) | Defined under RHIDP-15332 | `connector-config-hot-reload` | `specs/config-admin-ui/` | + +**No gaps found.** All RHDHPLAN-1513 frontend work has Jira coverage and openspec specifications. + +## OpenSpec Changes on This Branch Related to RHDHPLAN-1513 + +| OpenSpec Change | Related Epics | Frontend Specs? | +| ----------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| `ingestion-health-dashboard` | RHIDP-15331 | `admin-health-ui/` (frontend), `health-status-api/` (backend), `error-classification/` (backend) | +| `connector-config-hot-reload` | RHIDP-15332 | `config-admin-ui/` (frontend), `config-schemas/` (backend), `hot-reload-propagation/` (backend) | +| `ingestion-audit-metrics` | RHIDP-15333 (closed, partially absorbed into RHDHPLAN-1508) | `analytics-api/` (backend API consumed by RHDHPLAN-1509), `audit-events/` (backend), `eval-hub-integration/` (backend) | +| `upstream-schema-alignment` | RHIDP-15334 | `annotation-specification/` (docs), `migration-readiness-tooling/` (backend/CLI) | + +## Summary + +RHDHPLAN-1513 has **4 frontend stories** that are NOT in RHDHPLAN-1509's scope: + +- **3 admin health dashboard stories** (RHIDP-15336, 15338, 15339) under RHIDP-15331 that build the ingestion health admin dashboard with per-connector health cards, Neo4j sync panel, Force Sync actions, and air-gapped cluster differentiation +- **1 connector config admin UI story** (RHIDP-15342) under RHIDP-15332 that builds the runtime connector configuration section in Boost's admin panel + +All 4 stories have RHIDP Jira coverage and openspec specifications on this branch. No gaps. + +The relationship between RHDHPLAN-1513 and RHDHPLAN-1509 is clean: + +- **RHDHPLAN-1513** builds admin-facing operational UIs (health dashboard, connector config) and backend metrics APIs +- **RHDHPLAN-1509** builds developer-facing discovery UIs (browse, search, detail, Analytics tab) +- **RHDHPLAN-1513** exposes metrics via REST API → **RHDHPLAN-1509** renders them in the Analytics tab +- No overlap: admin operational tooling (1513) vs. developer discovery experience (1509) + +## Cross-Feature Frontend Summary (All 4 Features) + +| Feature | Frontend Stories NOT in RHDHPLAN-1509 | Total | +| ------------- | ----------------------------------------------------------------------------- | ----- | +| RHDHPLAN-1507 | None | 0 | +| RHDHPLAN-1508 | RHIDP-15273 (graduated visibility), RHIDP-15307/15308/15309 (RBAC admin UI) | 4 | +| RHDHPLAN-1510 | None | 0 | +| RHDHPLAN-1513 | RHIDP-15336/15338/15339 (health dashboard), RHIDP-15342 (connector config UI) | 4 | +| **Total** | | **8** | + +All 8 frontend stories have RHIDP Jira coverage and openspec specifications. No gaps across any feature. diff --git a/workspaces/boost/specifications/JIRA-analysis/cross-feature-frontend-summary.md b/workspaces/boost/specifications/JIRA-analysis/cross-feature-frontend-summary.md new file mode 100644 index 0000000000..6e211ae8eb --- /dev/null +++ b/workspaces/boost/specifications/JIRA-analysis/cross-feature-frontend-summary.md @@ -0,0 +1,95 @@ +# Cross-Feature Frontend Coverage Summary + +> **Date:** 2026-07-17 +> **Scope:** RHDHPLAN-1507, 1508, 1510, 1513 +> **Cross-referenced against:** RHDHPLAN-1509 (AI Catalog Discovery UI) + +## Overview + +8 frontend stories across 4 features fall outside RHDHPLAN-1509's scope. All 8 have RHIDP Jira coverage and openspec specifications on this branch. No gaps found. + +## Per-Feature Breakdown + +| Feature | Summary | Frontend Stories Outside 1509 | Count | +| ------------- | ------------------------------------------------ | --------------------------------------- | ----- | +| RHDHPLAN-1507 | AI Asset Entity Model & Ingestion Framework | None — purely backend SDK/ingestion | **0** | +| RHDHPLAN-1508 | AI Catalog RBAC & Versioning Policy Model | Graduated visibility UI + RBAC Admin UI | **4** | +| RHDHPLAN-1510 | MCP Registry & RHOAI Connector | None — purely backend connectors | **0** | +| RHDHPLAN-1513 | Ingestion Operations & Upstream Schema Alignment | Health dashboard + Connector config UI | **4** | +| | | **Total** | **8** | + +## The 8 Frontend Stories + +### RHDHPLAN-1508 — RBAC & Versioning Policy (4 stories) + +| Story | Epic | What It Builds | OpenSpec | +| ----------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | +| RHIDP-15273 | RHIDP-15270 (Graduated Visibility) | `RequirePermission` gating on entity detail pages — users with `ai-catalog.asset.read` but not `ai-catalog.asset.read.usage-docs` see redacted fields with "request access" placeholder. Also includes SkillBundle filtered-skill UX messaging. | `ai-catalog-asset-governance` `specs/graduated-visibility/` | +| RHIDP-15307 | RHIDP-15304 (RBAC Admin UI) | AI Catalog Policy Dashboard — summary view of active policies grouped by category and connector | `ai-catalog-asset-governance` `specs/rbac-admin-ui/` | +| RHIDP-15308 | RHIDP-15304 (RBAC Admin UI) | Category and Connector Policy Editor — create/edit/delete conditional RBAC policies, no raw YAML | `ai-catalog-asset-governance` `specs/rbac-admin-ui/` | +| RHIDP-15309 | RHIDP-15304 (RBAC Admin UI) | Default Posture Configuration — UI for default-allow/deny per category and per connector | `ai-catalog-asset-governance` `specs/default-deny-config/` | + +**Theme:** Permission-gated content rendering (1 story) + standalone RBAC admin page at `/ai-catalog/admin/rbac` (3 stories) + +### RHDHPLAN-1513 — Ingestion Operations (4 stories) + +| Story | Epic | What It Builds | OpenSpec | +| ----------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | +| RHIDP-15336 | RHIDP-15331 (Health Dashboard) | Per-connector health cards with status indicators (healthy/degraded/failing), timestamps, error summaries, "Force Sync" buttons. PatternFly design. | `ingestion-health-dashboard` `specs/admin-health-ui/` | +| RHIDP-15338 | RHIDP-15331 (Health Dashboard) | Neo4j graph sync status panel — sync timestamps, node/relationship counts, "Force Neo4j Re-sync" action | `ingestion-health-dashboard` `specs/admin-health-ui/` | +| RHIDP-15339 | RHIDP-15331 (Health Dashboard) | Disconnected-cluster health differentiation — visually distinguishes intentionally disabled connectors from enabled-but-failing | `ingestion-health-dashboard` `specs/admin-health-ui/` | +| RHIDP-15342 | RHIDP-15332 (Hot-Reload) | Admin UI for connector config — toggle enable/disable, endpoint URLs, sync schedules, K8s Secret references (read-only). Saves via AdminConfigService DB overrides. | `connector-config-hot-reload` `specs/config-admin-ui/` | + +**Theme:** Admin health dashboard in Boost admin panel (3 stories) + runtime connector config section (1 story) + +## Relationship to RHDHPLAN-1509 + +RHDHPLAN-1509 delivers the **developer-facing** AI Catalog frontend: + +- Browse page with search and filters (RHIDP-15166 — Closed) +- Entity page extensions and adoption actions (RHIDP-15167 — New) +- Extensible browse filters via NFS (RHIDP-15449 — Review) +- Translations, E2E tests, dynamic plugin export (RHIDP-15479, 15480, 15481) +- Analytics tab rendering (Journey 6 Step 16 — consumes RHDHPLAN-1513 metrics API) + +The 8 stories above are **admin-facing** and live in two distinct UI surfaces: + +1. **RBAC Admin UI** (RHDHPLAN-1508) — standalone page calling RBAC REST API directly, gated by `ai-catalog.admin` permission +2. **Boost Admin Panel** (RHDHPLAN-1513) — new sections in existing admin panel for health monitoring and connector config + +No overlap. RHDHPLAN-1509 renders entities; RHDHPLAN-1508 gates sections of those renderings; RHDHPLAN-1513 manages the connectors that produce them. + +## Interface Boundaries + +``` +Developer-facing (RHDHPLAN-1509) Admin-facing (1508 + 1513) +┌──────────────────────────────┐ ┌──────────────────────────────┐ +│ Browse Page (RHIDP-15166) │ │ RBAC Admin UI (RHIDP-15304) │ +│ Entity Page (RHIDP-15167) │◄────────│ Policy Dashboard (15307) │ +│ └─ RequirePermission gate │ gates │ Policy Editor (15308) │ +│ (RHIDP-15273) │ sections│ Default Posture (15309) │ +│ NFS Filters (RHIDP-15449) │ ├──────────────────────────────┤ +│ Analytics Tab (Journey 6) │◄────────│ Boost Admin Panel │ +│ │consumes │ Health Dashboard (15336) │ +│ │ metrics │ Neo4j Panel (15338) │ +│ │ API │ Air-gap Diff (15339) │ +│ │ │ Connector Config (15342) │ +└──────────────────────────────┘ └──────────────────────────────┘ + ▲ ▲ + │ displays │ manages + │ │ + ┌────┴──────────────────────────────────────────┴────┐ + │ Backend Connectors & SDK │ + │ RHDHPLAN-1507 (SDK) + RHDHPLAN-1510 (Connectors) │ + │ 0 frontend stories │ + └────────────────────────────────────────────────────┘ +``` + +## Conclusion + +All frontend needs across the 4 features are accounted for: + +- **RHDHPLAN-1509** covers all developer-facing discovery UI +- **8 admin-facing stories** (4 from 1508, 4 from 1513) are tracked with RHIDP Jiras and openspec specs +- **RHDHPLAN-1507 and 1510** are purely backend with zero frontend deliverables +- **No gaps** — every identified frontend need has a Jira story and an openspec specification From 5b4c17d2bb951edc3649f25920a050498951fb22 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Fri, 17 Jul 2026 11:19:48 -0400 Subject: [PATCH 08/18] fix(boost): RHDHPLAN-1505 clarify 1509 dependency hub and admin-facing frontend ownership - Add RHIDP-15167 dependency hub section with explicit Jira links - Clarify overview: 8 admin stories must be delivered independently of 1509 - Break out conclusion by feature: 1508 owns 4 stories, 1513 owns 4 stories Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../cross-feature-frontend-summary.md | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/workspaces/boost/specifications/JIRA-analysis/cross-feature-frontend-summary.md b/workspaces/boost/specifications/JIRA-analysis/cross-feature-frontend-summary.md index 6e211ae8eb..f948ba9a7a 100644 --- a/workspaces/boost/specifications/JIRA-analysis/cross-feature-frontend-summary.md +++ b/workspaces/boost/specifications/JIRA-analysis/cross-feature-frontend-summary.md @@ -6,7 +6,7 @@ ## Overview -8 frontend stories across 4 features fall outside RHDHPLAN-1509's scope. All 8 have RHIDP Jira coverage and openspec specifications on this branch. No gaps found. +RHDHPLAN-1509 covers all **developer-facing** discovery UI (browse, search, detail pages). However, **8 admin-facing frontend stories** across RHDHPLAN-1508 and RHDHPLAN-1513 fall outside RHDHPLAN-1509's scope and must be delivered independently. All 8 have RHIDP Jira coverage and openspec specifications on this branch. ## Per-Feature Breakdown @@ -46,8 +46,8 @@ RHDHPLAN-1509 delivers the **developer-facing** AI Catalog frontend: -- Browse page with search and filters (RHIDP-15166 — Closed) -- Entity page extensions and adoption actions (RHIDP-15167 — New) +- Browse page with search and filters (RHIDP-15166 — **Closed**) +- Entity page extensions and adoption actions (RHIDP-15167 — **New**) - Extensible browse filters via NFS (RHIDP-15449 — Review) - Translations, E2E tests, dynamic plugin export (RHIDP-15479, 15480, 15481) - Analytics tab rendering (Journey 6 Step 16 — consumes RHDHPLAN-1513 metrics API) @@ -59,6 +59,17 @@ The 8 stories above are **admin-facing** and live in two distinct UI surfaces: No overlap. RHDHPLAN-1509 renders entities; RHDHPLAN-1508 gates sections of those renderings; RHDHPLAN-1513 manages the connectors that produce them. +### RHIDP-15167 — The Key Open Dependency Hub + +With RHIDP-15166 (Browse page) already **Closed**, **RHIDP-15167** (Entity page extensions and adoption actions) is the remaining critical story under RHDHPLAN-1509 with active cross-feature dependencies: + +| Direction | Our Story | Relationship | Rationale | +| --------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------- | +| **RHIDP-15167 is depended on by** | RHIDP-15273 (RHDHPLAN-1508) | Graduated visibility frontend wraps RHIDP-15167's entity page components with `RequirePermission` gating | Cannot gate what hasn't been built yet | +| **RHIDP-15167 depends on** | RHIDP-15335 (RHDHPLAN-1513) | RHIDP-15167's Analytics tab (Journey 6 Step 16) consumes the per-connector health status API | Cannot render metrics without a metrics API | + +Both dependency links are registered in Jira as story-to-story "Depend" relationships. + ## Interface Boundaries ``` @@ -87,9 +98,8 @@ Developer-facing (RHDHPLAN-1509) Admin-facing (1508 + 1513) ## Conclusion -All frontend needs across the 4 features are accounted for: - -- **RHDHPLAN-1509** covers all developer-facing discovery UI -- **8 admin-facing stories** (4 from 1508, 4 from 1513) are tracked with RHIDP Jiras and openspec specs +- **RHDHPLAN-1509** covers all **developer-facing** discovery UI (browse, search, detail pages, Analytics tab) +- **RHDHPLAN-1508** owns **4 admin-facing frontend stories** not covered by RHDHPLAN-1509: graduated visibility gating (RHIDP-15273) and RBAC Admin UI (RHIDP-15307, 15308, 15309) +- **RHDHPLAN-1513** owns **4 admin-facing frontend stories** not covered by RHDHPLAN-1509: ingestion health dashboard (RHIDP-15336, 15338, 15339) and connector config UI (RHIDP-15342) - **RHDHPLAN-1507 and 1510** are purely backend with zero frontend deliverables - **No gaps** — every identified frontend need has a Jira story and an openspec specification From 0b1f7a2092c1e6d283e2cf4018d3c64b2971c550 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Fri, 17 Jul 2026 15:09:22 -0400 Subject: [PATCH 09/18] docs(boost): RHDHPLAN-1505 staged GitHub issues for 1507/1508/1510/1513 29 issues across 3 dependency tiers covering Entity Model, RBAC, Connectors, and Ingestion Ops. Each issue scoped for single fullsend /fs-code run with openspec task references, spec file paths, and explicit dependency chains. Tier 0: 7 issues (no deps, all parallel) Tier 1: 15 issues (depend on Tier 0) Tier 2: 7 issues (depend on Tier 1) Includes Jira-to-GitHub story mapping table for 8 RHIDP stories that span multiple issues due to tiered dependencies. Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../rhdhplan1505-1-staged-issues.md | 1383 +++++++++++++++++ 1 file changed, 1383 insertions(+) create mode 100644 workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md diff --git a/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md new file mode 100644 index 0000000000..09c03c85a1 --- /dev/null +++ b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md @@ -0,0 +1,1383 @@ +# RHDHPLAN-1505 — AI Catalog Entity Model, RBAC, Connectors & Ingestion Ops — Staged GitHub Issues + +These issues implement the AI Catalog backend across RHDHPLAN-1507 (Entity Model & Ingestion Framework), RHDHPLAN-1508 (RBAC & Versioning Policy), RHDHPLAN-1510 (MCP Registry & RHOAI Connector), and RHDHPLAN-1513 (Ingestion Operations & Schema Alignment). Issues are grouped in dependency tiers — Tier 0 issues have no dependencies and can run in parallel; Tier 1 depends on Tier 0; Tier 2 depends on Tier 1. + +Each issue is scoped for a single fullsend `/fs-code` run. Frontend admin UI issues are included (RBAC Admin UI, Ingestion Health Dashboard, Connector Config Admin UI). Developer-facing discovery UI is covered by RHDHPLAN-1509 and is NOT in scope here. + +**Feature → Epic mapping:** + +| Feature | Epics | +| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| RHDHPLAN-1507 | RHIDP-15258 (Entity Model), RHIDP-15294 (OCI Skill Registry), RHIDP-15295 (Neo4j Knowledge Graph) | +| RHDHPLAN-1508 | RHIDP-15270 (Graduated Visibility), RHIDP-15274 (Version Policy Cascade), RHIDP-15277 (Audit Logging), RHIDP-15304 (RBAC Admin UI), RHIDP-15305 (Conditional Rules) | +| RHDHPLAN-1510 | RHIDP-15313 (MCP Registry), RHIDP-15314 (RHOAI Connector), RHIDP-15316 (Cross-Connector Shared Infra) | +| RHDHPLAN-1513 | RHIDP-15331 (Health Dashboard), RHIDP-15332 (Hot-Reload), RHIDP-15334 (Schema Alignment) | + +**Cross-feature dependencies (RHDHPLAN-1509):** + +- Issue 24 (RHIDP-15273 Graduated Visibility Frontend) depends on RHIDP-15167 (Entity page extensions, RHDHPLAN-1509) +- RHIDP-15167 (RHDHPLAN-1509) depends on RHIDP-15335 (Issue 5 — Health API), creating a cross-feature cycle that must be resolved by building the API (Issue 5) first + +**Maximum parallelism:** All 7 Tier 0 issues can start simultaneously. Within Tier 1, issues [17–19] (Neo4j) are independent of [9–12] (OCI) and [13–16] (MCP/RHOAI). Within Tier 2, issues [23–25] (RBAC UI) are independent of [26–29] (Ingestion UI). + +**Jira-to-GitHub issue mapping is not 1:1.** GitHub issues are scoped for single fullsend `/fs-code` runs, while Jira stories are scoped by feature deliverable. When a Jira story defines an interface or foundation that later issues adopt or extend, the story's work naturally splits across dependency tiers — you define the annotation scheme in Tier 0 before providers can emit those annotations in Tier 1. The alternative (combining tiers into one larger issue) would defeat single-fullsend scoping and block parallelism. Five RHIDP stories have work split this way; three additional stories are referenced after completion as dependencies. The Jira story cannot be closed until the "Completed" issue finishes. + +For now, we will be employing the RHDH process convention used for our Jira tracking for upstream work, where we'll remove RHDIP stories from sprints as needed, and put into Waiting, if there are sprint wide gaps for implementing various stages of a story. +But as we progress, if further break up of a story is more seamless, we'll pursue that. But in other words, we will be honoring the Story granularity conventions in the RHDH skills used to craft our stories. + +| RHIDP Story | Started (definition/foundation) | Completed (adoption/extension) | Referenced after completion | +| --------------------------------------------- | -------------------------------------------------- | ---------------------------------------------------- | --------------------------------------------- | +| RHIDP-15255 (Annotation Scheme) | Issue 2 — define annotations + validator | Issue 8 — update providers to emit annotations | — | +| RHIDP-15260 (SDK Package) | Issue 2 — create package + interfaces | Issue 8 — delta sync framework + publish | — | +| RHIDP-15273 (Graduated Visibility) | Issue 23 — SkillBundle filtered-skill UX | Issue 24 — RequirePermission gating on entity detail | — | +| RHIDP-15280 (Audit Logging) | Issue 21 — define + emit audit events | Issue 29 — analytics REST API consuming audit data | — | +| RHIDP-15306 (Admin Permission + Default-Deny) | Issue 3 — define `ai-catalog.admin` permission | Issue 20 — implement default-deny config | — | +| RHIDP-15316 (Shared Infra) | Issue 1 — build `@boost/connector-utils` | Issue 1 | Issues 13, 16 (integrate CA bundle utility) | +| RHIDP-15335 (Health API) | Issue 5 — health API + data model | Issue 26 — force sync routes using health data | — | +| RHIDP-15259 (SDK Interface) | Issue 2 — define `AIAssetEntityProvider` interface | Issue 2 | Issue 8 (providers compile against interface) | + +--- + +# Tier 0 — No Dependencies (7 issues, all parallelizable) + +--- + +## Cross-Connector Shared Infrastructure Package (issue 1 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Dependencies:** None +**RHIDP Stories:** RHIDP-15265, RHIDP-15266, RHIDP-15329, RHIDP-15330 +**Feature:** RHDHPLAN-1510 — Epic RHIDP-15316 + +Create the `@boost/connector-utils` shared package providing CA bundle resolution, fault isolation wrappers, enable/disable patterns, and configurable endpoint/credential validation. All entity-provider connectors (MCP Registry, RHOAI, OCI Skill) depend on this package. Includes reference app-config YAML for air-gapped deployment with Helm and Operator CR examples. + +### Tasks + +From `openspec/changes/connector-shared-infrastructure/tasks.md` group 1 (RHIDP-15329): + +- 1.1 Create `@boost/connector-utils` package with `package.json`, TypeScript config, and README +- 1.2 Define `loadCaBundle(config: Config, connectorId: string): Buffer | undefined` function signature +- 1.3 Implement caFile resolution — read CA from `catalog.providers..tls.caFile` mount path +- 1.4 Implement caSecret resolution — read CA from `catalog.providers..tls.caSecret.$env` environment variable +- 1.5 Add per-connector config isolation — `loadCaBundle()` reads only the specified connector's CA config +- 1.6 Create `https.Agent` factory utility: `createHttpsAgent(caBundle?: Buffer): https.Agent | undefined` +- 1.7 Handle missing CA file: log INFO-level warning with expected file path, return `undefined` +- 1.8 Handle invalid/expired CA certificate: log ERROR with certificate details +- 1.9 Support CA certificate chains (concatenated PEM blocks) +- 1.10–1.15 Unit tests for CA bundle utility (file path, env var, missing, invalid, chain, isolation) + +From `openspec/changes/connector-shared-infrastructure/tasks.md` group 2 (RHIDP-15330): + +- 2.1 Define `ConnectorErrorContext` interface +- 2.2 Create `createProviderWrapper(provider, logger): EntityProvider` function +- 2.3 Implement try/catch wrapper around `provider.run()` to catch unhandled rejections +- 2.4 Implement structured error logging with connector context fields +- 2.5 Log errors via Backstage `LoggerService` for structured JSON output +- 2.6 Ensure wrapper does NOT rethrow errors — allow catalog backend to continue +- 2.7 Verify Backstage entity bucket isolation per provider +- 2.8–2.10 Unit tests for fault isolation wrapper + +From `openspec/changes/connector-shared-infrastructure/tasks.md` group 3 (RHIDP-15330): + +- 3.1 Define enable/disable config schema: `catalog.providers..enabled: boolean` +- 3.2 Create `isConnectorEnabled(config, connectorId): boolean` utility +- 3.3 Implement config reader: return `true` if `enabled` is omitted (default enabled) +- 3.4 Create registration guard pattern for backend module `init()` example in README +- 3.5 Log INFO-level message when connector is disabled +- 3.6 Verify disabled connector uses zero resources +- 3.7–3.10 Unit tests for enable/disable pattern + +From `openspec/changes/connector-shared-infrastructure/tasks.md` group 4: + +- 4.1 Export shared utilities from `src/index.ts` +- 4.2–4.7 Documentation: app-config schema, enable/disable, error logging, examples for each connector +- 4.8 Add JSDoc comments for all exported functions + +From `openspec/changes/connector-shared-infrastructure/tasks.md` group 5: + +- 5.1–5.6 Integration tests: CA from file, CA from env, https.Agent with custom CA, provider failure containment, disabled connector skip, structured error log + +From `openspec/changes/connector-shared-infrastructure/tasks.md` group 6 (RHIDP-15266): + +- 6.1 Create reference `app-config.yaml` snippet (endpoint URL, CA bundle, Secret-based creds, sync schedule) +- 6.2 Include MCP Registry connector example +- 6.3 Include RHOAI connector example +- 6.4 Include OCI Skill connector example +- 6.5 Document each config field with inline comments +- 6.6 Add air-gapped deployment variant +- 6.7 Place reference YAML in `workspaces/boost/examples/` + +From `openspec/changes/ai-catalog-entity-model/tasks.md` group 6 (RHIDP-15265 — moved to RHIDP-15316): + +- 6.3 Implement startup validation rejecting plaintext credentials with descriptive error message +- 6.4 Add `$secret` reference support for all credential fields +- 6.5 Implement configurable endpoint URLs (`baseUrl`) for all providers with startup validation + +### Specifications + +- `openspec/changes/connector-shared-infrastructure/specs/ca-bundle-resolution/spec.md` +- `openspec/changes/connector-shared-infrastructure/specs/fault-isolation/spec.md` +- `openspec/changes/connector-shared-infrastructure/specs/reference-app-config/spec.md` +- `openspec/changes/ai-catalog-entity-model/specs/air-gapped-deployment/spec.md` + +--- + +## Entity-Provider SDK — Types, Interfaces, Annotation Validation (issue 2 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Dependencies:** None +**RHIDP Stories:** RHIDP-15255, RHIDP-15259, RHIDP-15303 +**Feature:** RHDHPLAN-1507 — Epic RHIDP-15258 + +Create the `@boost/entity-provider-sdk` package with the AI Asset annotation scheme (`rhdh.io/ai-asset-category`, `rhdh.io/ai-asset-version`, `rhdh.io/ai-asset-source`), version normalization utility, CatalogProcessor validator, `AIAssetEntityProvider` interface definition, `Neo4jSyncAdapter` interface, and `SkillBundleMetadata` type. This issue establishes all type contracts — the delta sync framework and package publishing are in Issue 8. + +### Tasks + +From `openspec/changes/ai-catalog-entity-model/tasks.md` group 1 (RHIDP-15255): + +- 1.1 Define `rhdh.io/ai-asset-category` annotation constant and allowed values enum +- 1.2 Define `rhdh.io/ai-asset-version` annotation constant +- 1.3 Define `rhdh.io/ai-asset-source` annotation constant +- 1.4 Implement `normalizeAIAssetVersion(sourceVersion)` utility with all four normalization rules +- 1.5 Add unit tests for `normalizeAIAssetVersion()` +- 1.6 Implement CatalogProcessor validator rejecting entities with missing/invalid annotations +- 1.7 Add unit tests for CatalogProcessor validator + +From `openspec/changes/ai-catalog-entity-model/tasks.md` group 2 (RHIDP-15259, RHIDP-15260 — package+interface): + +- 2.1 Create `@boost/entity-provider-sdk` package with `package.json`, `tsconfig.json`, `README.md` +- 2.2 Define `AIAssetEntityProvider` TypeScript interface with required methods: `connect()`, `* entities()`, `getProviderName()`, `getProviderId()` +- 2.3 Define optional `delta(cursor?: string)` method for incremental sync pattern +- 2.4 Export annotation constants: `AI_ASSET_CATEGORY_ANNOTATION`, `AI_ASSET_VERSION_ANNOTATION`, `AI_ASSET_SOURCE_ANNOTATION` +- 2.5 Implement `validateAIAssetEntity(entity)` utility throwing on missing/invalid annotations +- 2.6 Add unit tests for `validateAIAssetEntity()` + +From `openspec/changes/ai-catalog-entity-model/tasks.md` group 3 (RHIDP-15303): + +- 3.1 Define `Neo4jSyncAdapter` TypeScript interface with methods: `createNode()`, `updateNode()`, `deleteNode()`, `createRelationship()` +- 3.2 Define `RelationshipType` union type with constants: `DEPENDS_ON`, `USES_TOOL`, `BELONGS_TO`, `SIMILAR_TO`, `IMPLEMENTED_BY`, `INCLUDES` +- 3.3 Export `Neo4jSyncAdapter` interface from SDK package +- 3.4 Add JSDoc documentation to interface + +From `openspec/changes/ai-catalog-entity-model/tasks.md` group 4 (RHIDP-15303): + +- 4.1 Define `SkillBundleMetadata` TypeScript type with fields +- 4.2 Export `SkillBundleMetadata` type from SDK package +- 4.3 Add JSDoc documentation with example skillcard.yaml structure + +### Specifications + +- `openspec/changes/ai-catalog-entity-model/specs/annotation-scheme/spec.md` +- `openspec/changes/ai-catalog-entity-model/specs/entity-provider-sdk/spec.md` + +--- + +## AI Catalog Permissions, Backend Enforcement, Conditional Rules (issue 3 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Dependencies:** None +**RHIDP Stories:** RHIDP-15271, RHIDP-15272, RHIDP-15306 (permission definitions), RHIDP-15312 +**Feature:** RHDHPLAN-1508 — Epics RHIDP-15270, RHIDP-15305 + +Define AI Catalog permission constants (`ai-catalog.asset.read`, `ai-catalog.asset.read.usage-docs`, `ai-catalog.admin`), implement graduated visibility backend enforcement (Tier 1 entity-level + Tier 2 field-level filtering), and implement conditional permission rules (`isAiAssetCategory`, `isFromConnector`, `isInTenant`) with `toQuery()` support. The default-deny config implementation is in Issue 20. + +### Tasks + +From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 1 (RHIDP-15271, RHIDP-15306): + +- 1.1 Define `AI_CATALOG_ASSET_RESOURCE_TYPE` constant in `boost-common/src/permissions.ts` +- 1.2 Define `ai-catalog.asset.read` resource permission +- 1.3 Define `ai-catalog.asset.read.usage-docs` resource permission +- 1.4 Define `ai-catalog.admin` basic permission +- 1.5 Export all permission constants and resource type +- 1.6 Register all 3 permissions via `permissionsRegistry.addPermissions()` + +From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 2 (RHIDP-15271, RHIDP-15272): + +- 2.1 Implement Tier 2 field-level filtering in AI asset detail endpoint +- 2.2 Implement entity-level filtering on list endpoint using `authorizeConditional()` +- 2.3 Implement batch `authorizeConditional()` for Tier 2 +- 2.4 Add unit tests for field-level filtering + +From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 4 (RHIDP-15312): + +- 4.1 Implement `isAiAssetCategory` rule with `apply()` and `toQuery()` +- 4.2 Implement `isAiAssetCategory.toQuery()` generating catalog query predicate +- 4.3 Implement `isFromConnector` rule with `apply()` and `toQuery()` +- 4.4 Implement `isFromConnector.toQuery()` generating catalog query predicate +- 4.5 Implement `isInTenant` rule with `apply()` and `toQuery()` +- 4.6 Implement `isInTenant.toQuery()` generating catalog query predicate +- 4.7 Register all 3 rules via `createPermissionIntegrationRouter` with `resourceType: 'ai-catalog-asset'` +- 4.8 Add unit tests for each rule's `apply()` and `toQuery()` methods + +### Specifications + +- `openspec/changes/ai-catalog-asset-governance/specs/graduated-visibility/spec.md` +- `openspec/changes/ai-catalog-asset-governance/specs/conditional-policies/spec.md` + +--- + +## Upstream Schema Alignment — Annotation Spec, Migration Design & Tooling (issue 4 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Dependencies:** None +**RHIDP Stories:** RHIDP-15346, RHIDP-15347, RHIDP-15302 +**Feature:** RHDHPLAN-1513 — Epic RHIDP-15334 + RHDHPLAN-1507 — Epic RHIDP-15258 + +Document the annotation specification mapping `rhdh.io/ai-asset-*` annotations to upstream Backstage RFCs (#32062 McpServer, #33060 ai-model/ai-model-server), with confidence levels and transformation rules. Create the `@boost/migration-readiness` CLI scaffold for dry-run migration assessments. Create the migration design document with mapping tables and backward compatibility strategy. This is readiness assessment — actual migration is future work. + +### Tasks + +From `openspec/changes/upstream-schema-alignment/tasks.md` group 1 (RHIDP-15346): + +- 1.1 Document all `rhdh.io/ai-asset-category` values +- 1.2 Document `rhdh.io/ai-asset-version` annotation format and normalization rules +- 1.3 Document `rhdh.io/ai-asset-source` annotation format +- 1.4 Document entity kind + `spec.type` mapping table +- 1.5 Map each entity type to RFC #32062 (McpServer) target +- 1.6 Map each entity type to RFC #33060 (ai-model/ai-model-server) targets +- 1.7 Assign confidence levels to each mapping +- 1.8 Document fields requiring transformation per entity type +- 1.9 Add explicit "Future Work" section +- 1.10 Add header with draft status and last-updated date +- 1.11 Cross-reference `agent-creation-discovery/catalog-entities` spec +- 1.12 Publish spec in `workspaces/boost/specifications/` directory + +From `openspec/changes/upstream-schema-alignment/tasks.md` group 2 (RHIDP-15347): + +- 2.1 Create `@boost/migration-readiness` CLI package structure +- 2.2 Set up TypeScript configuration and build pipeline +- 2.3 Implement catalog API client for entity enumeration +- 2.4 Filter entities by `rhdh.io/ai-asset-category` annotation presence +- 2.5 Implement per-entity mapping logic using annotation spec rules +- 2.6 Generate per-entity report (current → target, transformations, confidence) +- 2.7 Implement JSON output formatter +- 2.8 Implement human-readable output formatter +- 2.9 Handle entities with missing annotation (exclude gracefully) +- 2.10 Handle entities with partial annotations (include with warning) +- 2.11 CLI argument parsing (`--catalog-url`, `--output-format`, `--filter`) +- 2.12 Add footer message: "This is a migration-readiness assessment" + +From `openspec/changes/upstream-schema-alignment/tasks.md` groups 3–5: + +- 3.1–3.10 Testing (mapping logic, confidence, transformations, mock catalog, edge cases) +- 4.1–4.8 Documentation (README, usage, output interpretation, confidence levels, future work) +- 5.1–5.5 Cross-references (RHDHPLAN-1507, RFCs, RHIDP-15302/15303) + +From `openspec/changes/ai-catalog-entity-model/tasks.md` group 8 (RHIDP-15302): + +- 8.1 Create migration design document with mapping table: current → target upstream kind +- 8.2 Document transformation rules for each AI asset category +- 8.3 Identify consumer-facing changes: catalog UI filters, entity refs, API queries +- 8.4 Document backward compatibility strategy +- 8.5 Obtain upstream Backstage maintainer or RHDH architect sign-off +- 8.6 Document sign-off in spec + +### Specifications + +- `openspec/changes/upstream-schema-alignment/specs/annotation-specification/spec.md` +- `openspec/changes/upstream-schema-alignment/specs/migration-readiness-tooling/spec.md` +- `openspec/changes/ai-catalog-entity-model/specs/migration-readiness/spec.md` + +--- + +## Ingestion Health — API, Data Model, Error Classification (issue 5 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Dependencies:** None +**RHIDP Stories:** RHIDP-15335, RHIDP-15337 +**Feature:** RHDHPLAN-1513 — Epic RHIDP-15331 + +Implement the ingestion health backend: `sync_attempts` table with database migration, `SyncAttemptsRepository`, `HealthStatusService` with status derivation (healthy/degraded/failing based on last 3 attempts), `GET /api/boost/ingestion-health` REST endpoint, and `ErrorClassifier` utility with actionable diagnostic guidance for auth failures, network errors, schema mismatches, and rate limits. The admin UI consuming this API is in Issue 26. + +### Tasks + +From `openspec/changes/ingestion-health-dashboard/tasks.md` group 1 (RHIDP-15335): + +- 1.1 Define `sync_attempts` table schema in database migration +- 1.2 Create database migration file with indexes on (connector_id, timestamp DESC) +- 1.3 Implement `SyncAttemptsRepository` class with methods: `insertSyncAttempt()`, `getLatestAttempts()`, `cleanupOldAttempts()` +- 1.4 Add retention policy config schema (`boost.ingestion.healthRetention.maxAttemptsPerConnector`, default 100) +- 1.5 Implement scheduled cleanup job for sync attempts (daily, enforces retention) +- 1.6 Add database indexes for efficient health status queries + +From `openspec/changes/ingestion-health-dashboard/tasks.md` group 2 (RHIDP-15335): + +- 2.1 Define `ConnectorHealthStatus` type in `plugins/boost-common/src/types/ingestion-health.ts` +- 2.2 Implement `GET /api/boost/ingestion-health` route returning array of connector health objects +- 2.3 Implement health status derivation logic in `HealthStatusService.deriveStatus(attempts)` +- 2.4 Add `?includeDisabled=true` query parameter support +- 2.5 Implement RBAC gating via boost admin permissions check +- 2.6 Add audit logging for health API requests +- 2.7 Implement empty state handling +- 2.8 Add health API integration tests + +From `openspec/changes/ingestion-health-dashboard/tasks.md` group 3 (RHIDP-15337): + +- 3.1 Create `ErrorClassifier` utility class +- 3.2 Implement `classify(error, options?)` method returning `{ errorType, errorMessage, diagnosticGuidance }` +- 3.3 Add auth failure detection patterns (401/403, "Invalid token", "OAuth expired") +- 3.4 Add network failure detection patterns (ECONNREFUSED, ETIMEDOUT, DNS, TLS) +- 3.5 Add schema mismatch detection patterns (JSON parsing, "Unexpected field", GraphQL) +- 3.6 Add rate limit detection patterns (429, X-RateLimit-Remaining) +- 3.7 Implement connector-specific error matchers +- 3.8 Implement unknown error fallback classification +- 3.9 Add diagnostic guidance text for each error type +- 3.10 Add error classification unit tests + +### Specifications + +- `openspec/changes/ingestion-health-dashboard/specs/health-status-api/spec.md` +- `openspec/changes/ingestion-health-dashboard/specs/error-classification/spec.md` + +--- + +## Connector Config — Zod Schemas and RuntimeConfigResolver Extension (issue 6 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Dependencies:** None +**RHIDP Stories:** RHIDP-15340 +**Feature:** RHDHPLAN-1513 — Epic RHIDP-15332 + +Define Zod connector config schemas (Jira, GitHub, GitLab) with field-level `configScope` annotations (`db-overridable` vs `yaml-only`), and extend `RuntimeConfigResolver` to support connector config scope with two-layer merge (YAML baseline + DB overrides), 30s TTL cache with immediate invalidation, and schema validation during merge. Hot-reload propagation to connectors is in Issue 22; admin UI is in Issue 28. + +### Tasks + +From `openspec/changes/connector-config-hot-reload/tasks.md` group 1 (RHIDP-15340): + +- 1.1 Define Jira connector config Zod schema with fields: `enabled`, `endpoint`, `schedule.*`, `credentials.*`, `namespace`, `batchSize`, `timeout.*` +- 1.2 Annotate each field with `configScope`: `enabled`, `endpoint`, `schedule.*`, `batchSize`, `timeout.*` → `db-overridable`; `credentials.*`, `namespace` → `yaml-only` +- 1.3 Define GitHub connector config Zod schema +- 1.4 Define GitLab connector config Zod schema +- 1.5 Add URL validation for `endpoint` field +- 1.6 Add positive number validation for numeric fields +- 1.7 Add cron expression validation for `schedule.cron` +- 1.8 Define default values in schemas +- 1.9 Add schema versioning field +- 1.10 Add unit tests for schema validation + +From `openspec/changes/connector-config-hot-reload/tasks.md` group 2 (RHIDP-15340): + +- 2.1 Extend `RuntimeConfigResolver` to support connector config scope +- 2.2 Implement `getConfig(key)` method for connector config keys +- 2.3 Implement two-layer merge: YAML baseline from `ConfigApi` + DB overrides from `AdminConfigService` +- 2.4 Implement cache with 30s TTL for merged connector config +- 2.5 Implement immediate cache invalidation on DB override write +- 2.6 Add Zod schema validation during merge +- 2.7 Implement `configScope` enforcement: reject DB override writes for `yaml-only` fields +- 2.8 Add schema version migration logic for backward compatibility +- 2.9 Add unit tests for two-layer merge +- 2.10 Add integration tests for `RuntimeConfigResolver` with connector schemas + +### Specifications + +- `openspec/changes/connector-config-hot-reload/specs/config-schemas/spec.md` + +--- + +## MCP Mirror Endpoint + RHOAI Version Normalization (issue 7 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Dependencies:** None +**RHIDP Stories:** RHIDP-15317, RHIDP-15321 +**Feature:** RHDHPLAN-1510 — Epics RHIDP-15313, RHIDP-15314 + +Implement the MCP Registry mirror endpoint configuration with zero-internet validation (no outbound traffic to public endpoint when mirror is configured), startup health check, and non-HTTPS security warnings. Also implement RHOAI version normalization utility for MCP server entity `rhdh.io/ai-asset-version` annotation population. These two stories have no cross-connector dependencies and can start immediately. + +### Tasks + +From `openspec/changes/mcp-registry-connector/tasks.md` group 1 (RHIDP-15317): + +- 1.1 Add `catalog.providers.mcpRegistry.endpoint` config schema in `config.d.ts` +- 1.2 Implement endpoint configuration loading from app-config +- 1.3 Add environment variable override support (`MCP_REGISTRY_ENDPOINT`) +- 1.4 Implement endpoint URL validation +- 1.5 Add endpoint fallback logic (app-config > env var > default public endpoint) +- 1.6 Implement startup endpoint validation health check +- 1.7 Add endpoint configuration logging at connector startup +- 1.8 Add security warning for non-HTTPS endpoints +- 1.9 Implement HTTP client configuration with mirror endpoint URL +- 1.10 Add Prometheus metrics for endpoint request count, latency, error rate +- 1.11 Add Prometheus metric for public endpoint violation detection +- 1.12–1.18 Integration tests: zero outbound traffic, mirror targeting, DNS resolution, retry backoff, invalid URL, non-HTTPS warning, override precedence +- 1.19–1.20 Documentation: mirror endpoint examples, zero-internet validation + +From `openspec/changes/rhoai-connector/tasks.md` group 7 (RHIDP-15321): + +- 7.1 Define version normalization rules +- 7.2 Implement `normalizeVersion(rawVersion)` utility — semver normalization, strip `v` prefix, handle `latest`/`nightly` +- 7.3 Populate `rhdh.io/ai-asset-version` annotation with normalized version +- 7.4 Handle missing version metadata: set `"unknown"` with DEBUG log +- 7.5 Handle invalid version strings: set `"unknown"` with WARNING log +- 7.6 Unit tests for version normalization +- 7.7 Integration test: emitted entities carry correct annotation + +### Specifications + +- `openspec/changes/mcp-registry-connector/specs/mirror-endpoint/spec.md` +- `openspec/changes/rhoai-connector/specs/mcp-catalog-source/spec.md` + +--- + +# Tier 1 — Depends on Tier 0 (15 issues) + +--- + +## SDK — Delta Sync Framework and Package Publish (issue 8 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 1 (shared infra exports), Issue 2 (types/interfaces) +**RHIDP Stories:** RHIDP-15260, RHIDP-15262 +**Feature:** RHDHPLAN-1507 — Epic RHIDP-15258 + +Implement the `DeltaSyncManager` class with `applyDelta()` method translating connector deltas to catalog mutations, sync cursor persistence in catalog database, and fallback to full refresh when cursor is invalid. Update existing providers (Kagenti, LlamaStack) to emit entities with required AI Asset annotations. Publish SDK package to npm registry. Write SDK documentation with interface contract, annotation scheme, and code examples. + +### Tasks + +From `openspec/changes/ai-catalog-entity-model/tasks.md` group 2 (RHIDP-15260, RHIDP-15262): + +- 2.7 Publish SDK package to npm registry with semver versioning (RHIDP-15260) +- 2.8 Implement `DeltaSyncManager` class wrapping `applyMutation({ type: 'delta' })` API (RHIDP-15262) +- 2.9 Add `applyDelta({ added, updated, removed, nextCursor })` method (RHIDP-15262) +- 2.10 Implement sync cursor persistence using catalog database (RHIDP-15262) +- 2.11 Implement `getCursor(providerId)` method retrieving last persisted cursor (RHIDP-15262) +- 2.12 Implement fallback to full refresh when cursor invalid or missing (RHIDP-15262) +- 2.13 Add unit tests for delta sync framework (RHIDP-15262) + +From `openspec/changes/ai-catalog-entity-model/tasks.md` group 5 (RHIDP-15255, RHIDP-15259): + +- 5.1 Update Kagenti provider to emit entities with all three required annotations +- 5.2 Update LlamaStack provider to emit entities with all three required annotations +- 5.3 Verify Kagenti provider compiles against SDK interface without errors +- 5.4 Verify LlamaStack provider compiles against SDK interface without errors + +From `openspec/changes/ai-catalog-entity-model/tasks.md` group 9 (RHIDP-15260): + +- 9.1 Write SDK package README documenting interface contract, annotation constants, validation usage +- 9.2 Add code examples to README showing provider implementation +- 9.3 Document version normalization rules in SDK README +- 9.5 Create `CHANGELOG.md` with initial version entry + +### Specifications + +- `openspec/changes/ai-catalog-entity-model/specs/entity-provider-sdk/spec.md` +- `openspec/changes/ai-catalog-entity-model/specs/delta-sync-framework/spec.md` + +--- + +## OCI Skill Registry — Core Connector (issue 9 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 1 (shared infra), Issue 8 (SDK) +**RHIDP Stories:** RHIDP-15296 +**Feature:** RHDHPLAN-1507 — Epic RHIDP-15294 + +Implement the core OCI Skill Registry connector: OCI Distribution Spec client for tag listing, manifest fetching, and blob download; skillcard extraction from OCI image layers with YAML parsing and SDK schema validation; entity emission as `kind: AIResource` with `spec.type: skill` and all required annotations; backend module registration with `createBackendModule`. This is the foundational OCI connector — multi-registry config, incremental sync, and load testing are separate issues. + +### Tasks + +From `openspec/changes/oci-skill-registry/tasks.md` group 1 (RHIDP-15296): + +- 1.1 Evaluate and select Node.js OCI Distribution Spec client library +- 1.2 Implement `OciRegistryClient` class with methods: `listTags()`, `getManifest()`, `getBlob()` +- 1.5 Write unit tests for OCI client with mocked registry responses + +From `openspec/changes/oci-skill-registry/tasks.md` group 2 (RHIDP-15296): + +- 2.1 Implement layer blob download with streaming decompression +- 2.2 Implement tar stream parser to extract `skillcard.yaml` +- 2.3 Integrate SDK schema validator for `skillcard.yaml` validation +- 2.4 Implement error handling for missing/invalid `skillcard.yaml` +- 2.5–2.6 Unit tests for skillcard extraction and schema validation + +From `openspec/changes/oci-skill-registry/tasks.md` group 3 (RHIDP-15296): + +- 3.1 Implement `OciSkillRegistryProvider` class extending `EntityProvider` interface +- 3.2 Implement entity factory: convert `skillcard.yaml` to Backstage `Resource` entity +- 3.3 Populate required annotations: `rhdh.io/ai-asset-category`, `rhdh.io/ai-asset-version`, `rhdh.io/ai-asset-source` +- 3.4 Implement entity ref sanitization +- 3.5 Write unit tests for entity emission + +From `openspec/changes/oci-skill-registry/tasks.md` group 6 (RHIDP-15296): + +- 6.1 Implement backend module with `createBackendModule({ pluginId: 'catalog', moduleId: 'ai-catalog-oci-skill-registry' })` +- 6.2 Register entity provider via `catalogProcessingExtensionPoint` +- 6.4 Write integration test for module registration + +From `openspec/changes/oci-skill-connector/tasks.md` group 1 (RHIDP-15324): + +- 1.1–1.11 OCI registry client: tag listing, manifest fetching, Docker v2 fallback, digest extraction, pagination, namespace filtering, parallel manifest fetch, OCI annotations, blob download, gzip decompression, unit tests + +From `openspec/changes/oci-skill-connector/tasks.md` group 2 (RHIDP-15325): + +- 2.1–2.15 Skillcard parsing: layer identification, YAML parsing, Zod validation, error logging, entity building as `kind: AIResource`, annotation population, default values, invalid skill rejection, aggregate summary, unit tests + +### Specifications + +- `openspec/changes/oci-skill-registry/specs/oci-artifact-ingestion/spec.md` +- `openspec/changes/oci-skill-connector/specs/registry-discovery/spec.md` +- `openspec/changes/oci-skill-connector/specs/skillcard-parsing/spec.md` + +--- + +## OCI — Multi-Registry and Air-Gapped Support (issue 10 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 1 (shared infra), Issue 9 (core connector) +**RHIDP Stories:** RHIDP-15297 +**Feature:** RHDHPLAN-1507 — Epic RHIDP-15294 + +Add multi-registry configuration support (distinct credentials, CA bundles, and sync schedules per registry instance), K8s pull secret loader with Docker `config.json` parsing, custom CA bundle integration via shared `@boost/connector-utils`, and air-gapped registry support with no external DNS resolution. + +### Tasks + +From `openspec/changes/oci-skill-registry/tasks.md` group 4 (RHIDP-15297): + +- 4.1 Define app-config schema for `ai-catalog-oci-skill-registry` with registry instances +- 4.2 Implement config parser with validation +- 4.3 Implement Secret loader for registry credentials +- 4.4 Implement ConfigMap/Secret loader for custom CA bundles +- 4.5 Implement per-registry sync interval scheduling +- 4.6–4.7 Unit tests and integration test for multi-registry + +From `openspec/changes/oci-skill-connector/tasks.md` group 4 (RHIDP-15327): + +- 4.1–4.15 Auth and air-gapped: K8s pull secret loader, Docker config.json parsing, Basic Auth, missing pull secret handling, custom CA bundle, shared CA utility integration, system CA fallback, per-registry auth, credential reuse, air-gapped registry support, DNS resolution failure handling, unit and integration tests + +### Specifications + +- `openspec/changes/oci-skill-registry/specs/multi-registry-config/spec.md` + +--- + +## OCI — Digest-Based Incremental Sync (issue 11 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 1 (shared infra), Issue 9 (core connector) +**RHIDP Stories:** RHIDP-15298 +**Feature:** RHDHPLAN-1507 — Epic RHIDP-15294 + +Implement digest-based incremental sync: cursor storage schema (registryId, namespace, tagDigestMap, lastSync), tag-to-digest comparison detecting new/changed/removed tags, change detection algorithm translating to add/update/delete entity mutations, full refresh fallback for invalid cursors, and in-memory digest cache with 5-minute TTL and disk persistence. + +### Tasks + +From `openspec/changes/oci-skill-registry/tasks.md` group 5 (RHIDP-15298): + +- 5.1 Define cursor storage schema +- 5.2 Implement cursor persistence layer +- 5.3 Implement tag-to-digest comparison logic +- 5.4 Implement change detection algorithm +- 5.5 Implement full refresh fallback +- 5.6–5.7 Unit tests and performance test for incremental sync + +From `openspec/changes/oci-skill-connector/tasks.md` group 3 (RHIDP-15326): + +- 3.1 Implement in-memory digest cache +- 3.2 Implement 5-minute TTL on cache entries +- 3.3 Implement digest comparison logic: detect added, changed, removed skills +- 3.4 Implement delta mutation emission via `applyMutation({ type: 'delta' })` +- 3.5 Implement full mutation on first sync +- 3.6 Implement disk persistence +- 3.7 Implement disk cache loading on startup +- 3.8 Implement cache re-validation after TTL expiration +- 3.9–3.10 Unit and integration tests for cache logic + +### Specifications + +- `openspec/changes/oci-skill-registry/specs/digest-based-sync/spec.md` +- `openspec/changes/oci-skill-connector/specs/incremental-sync-scale/spec.md` + +--- + +## OCI — Load Testing and Scale Validation (issue 12 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 1 (shared infra), Issue 9 (core connector) +**RHIDP Stories:** RHIDP-15268 +**Feature:** RHDHPLAN-1507 — Epics RHIDP-15258, RHIDP-15294 + +Create load test harness generating 5,000+ AI asset entities, measure baseline vs with-AI-Catalog p95 latency (SLA: ≤10% degradation), validate processing-loop duration (entity emission → catalog API availability), and validate 2,000-image OCI sync completes within 5 minutes with peak memory under 500 MB. + +### Tasks + +From `openspec/changes/ai-catalog-entity-model/tasks.md` group 7 (RHIDP-15268): + +- 7.1 Create load test harness generating 5,000+ AI asset entities +- 7.2 Measure baseline p95 latency without AI Catalog entities +- 7.3 Measure with-AI-Catalog p95 latency with 5,000+ entities +- 7.4 Validate p95 latency degradation ≤10% SLA +- 7.5 Measure processing-loop duration +- 7.6 Document load test execution steps in `tests/load/README.md` + +From `openspec/changes/oci-skill-connector/tasks.md` group 5 (RHIDP-15328): + +- 5.1 Create mock OCI registry test harness with 2,000 synthetic skill images +- 5.2 Implement mock registry endpoints +- 5.3 Implement parallel manifest fetch with configurable concurrency +- 5.4 Implement batch processing (100 per batch) +- 5.5 Implement memory-bounded processing +- 5.6 Validate full sync of 2,000 images within 5 minutes +- 5.7 Validate incremental sync with 10% churn within 2 minutes +- 5.8 Log throughput and memory usage +- 5.9 Fail if throughput drops below 6 images/second +- 5.10 Verify peak memory under 500 MB + +### Specifications + +- `openspec/changes/ai-catalog-entity-model/specs/performance-resilience/spec.md` +- `openspec/changes/oci-skill-connector/specs/incremental-sync-scale/spec.md` + +--- + +## MCP Registry — TLS and Credential Hardening (issue 13 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 1 (shared infra), Issue 7 (mirror endpoint) +**RHIDP Stories:** RHIDP-15318 +**Feature:** RHDHPLAN-1510 — Epic RHIDP-15313 + +Integrate shared CA bundle utility (`loadCaBundle()`) from `@boost/connector-utils`, implement K8s Secret-based authentication (Basic Auth and Bearer token), Secret data caching with 5-minute TTL and invalidation on 401, and per-connector TLS configuration isolation. + +### Tasks + +From `openspec/changes/mcp-registry-connector/tasks.md` group 2 (RHIDP-15318): + +- 2.1 Integrate shared CA bundle utility from RHIDP-15316 +- 2.2 Add `catalog.providers.mcpRegistry.tls.ca` config schema +- 2.3 Implement custom CA bundle loading from file path +- 2.4 Add graceful degradation: invalid CA bundle falls back to system CA +- 2.5 Add warning logging for invalid CA bundle files +- 2.6 Implement HTTPS agent configuration with custom CA bundle +- 2.7 Enforce TLS certificate validation (`rejectUnauthorized: true`) +- 2.8 Add `catalog.providers.mcpRegistry.auth.secretRef` config schema +- 2.9 Implement K8s Secret reading +- 2.10 Implement credential extraction from Secret +- 2.11 Implement HTTP Basic Auth for username/password +- 2.12 Implement Bearer token authentication +- 2.13 Implement Secret data caching with 5-minute TTL +- 2.14 Implement cache invalidation on HTTP 401 +- 2.15 Add error handling: missing Secret, missing credential keys, invalid Secret data +- 2.16 Add per-connector TLS configuration isolation +- 2.17–2.18 Prometheus metrics for TLS and auth +- 2.19–2.26 Integration tests for CA bundle, K8s Secret, cache invalidation, per-connector isolation +- 2.27–2.29 Documentation: CA bundle config, K8s Secret auth, Secret rotation + +### Specifications + +- `openspec/changes/mcp-registry-connector/specs/auth-tls-hardening/spec.md` + +--- + +## MCP Registry — AI Asset Annotation Enrichment (issue 14 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 8 (SDK validation layer), Issue 13 (TLS hardening) +**RHIDP Stories:** RHIDP-15319 +**Feature:** RHDHPLAN-1510 — Epic RHIDP-15313 + +Implement `RhdhMcpRegistryProviderWrapper` class intercepting entity emission to enrich with AI Asset annotations (`rhdh.io/ai-asset-category: "mcp-server"`, `rhdh.io/ai-asset-source: "mcp-registry"`, extracted version), integrate with SDK validation layer, and preserve existing annotations. + +### Tasks + +From `openspec/changes/mcp-registry-connector/tasks.md` group 3 (RHIDP-15319): + +- 3.1 Implement `RhdhMcpRegistryProviderWrapper` class wrapping upstream connector +- 3.2 Implement entity emission interception before `applyMutation` +- 3.3 Implement annotation enrichment logic (`enrichWithAiAssetAnnotations()`) +- 3.4 Add `rhdh.io/ai-asset-category: "mcp-server"` annotation +- 3.5 Add `rhdh.io/ai-asset-source: "mcp-registry"` annotation +- 3.6 Implement version metadata extraction from MCP server manifest +- 3.7 Add `rhdh.io/ai-asset-version` annotation (extracted or "unknown") +- 3.8 Add graceful degradation: enrichment failure logs warning, emits entity without annotations +- 3.9 Add preservation logic: do not overwrite existing AI Asset annotations +- 3.10 Add DEBUG-level logging for enriched entities +- 3.11 Integrate with RHDHPLAN-1507's SDK validation layer +- 3.12–3.14 Prometheus metrics for enrichment +- 3.15–3.21 Unit and integration tests +- 3.22–3.23 Documentation + +### Specifications + +- `openspec/changes/mcp-registry-connector/specs/annotation-enrichment/spec.md` + +--- + +## RHOAI — MCP Catalog Source and Module Scaffold (issue 15 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 8 (SDK annotation scheme) +**RHIDP Stories:** RHIDP-15322 +**Feature:** RHDHPLAN-1510 — Epic RHIDP-15314 + +Implement `RhoaiMcpCatalogProvider` with graceful 404 handling for developer-preview MCP catalog API, entity mapping (MCP catalog entry → API with `spec.type: mcp-server`), API response schema validation with Zod, and retry logic for unavailable API. Scaffold `catalog-backend-module-rhoai` backend module package. + +### Tasks + +From `openspec/changes/rhoai-connector/tasks.md` group 1 (RHIDP-15322): + +- 1.1 Define RHOAI MCP catalog API response types with Zod schemas +- 1.2 Implement `McpCatalogApiClient` with typed fetch +- 1.3 Implement `RhoaiMcpCatalogProvider` extending `EntityProvider` +- 1.4 Implement entity mapper: MCP catalog entry → API with `spec.type: mcp-server` +- 1.5 Add MCP-specific annotations +- 1.6 Implement `connect()` method with graceful 404 handling and `mcpApiAvailable` flag +- 1.7 Implement `read()` method returning empty array when API unavailable +- 1.8 Implement retry logic: every 10th refresh cycle +- 1.9 Implement API response schema validation with Zod +- 1.10 Add `rhdh.io/api-version-mismatch` annotation when API version differs +- 1.11 Add standard RHDH annotations +- 1.12 Implement logging for API availability transitions + +From `openspec/changes/rhoai-connector/tasks.md` group 3: + +- 3.1 Create `plugins/catalog-backend-module-rhoai/` package directory +- 3.2 Create `package.json` with Backstage backend module role +- 3.3 Create module entry point with `createBackendModule` +- 3.4 Register `RhoaiMcpCatalogProvider` when enabled +- 3.5 Add module to `backend/src/index.ts` +- 3.6 Configure TypeScript build +- 3.7 Add ESLint and Prettier configuration + +### Specifications + +- `openspec/changes/rhoai-connector/specs/mcp-catalog-source/spec.md` + +--- + +## RHOAI — Deployment Config and Cross-Cluster Endpoint (issue 16 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 1 (shared infra CA/credential utils), Issue 15 (MCP catalog provider) +**RHIDP Stories:** RHIDP-15323 +**Feature:** RHDHPLAN-1510 — Epic RHIDP-15314 + +Implement deployment configuration for RHOAI connector: Zod config schema for `catalog.providers.rhoai.mcpCatalog`, enable/disable toggle, K8s Secret loader for credentials, shared CA bundle integration, Secret refresh per reconciliation cycle (no credential caching), and startup logging with graceful error handling. + +### Tasks + +From `openspec/changes/rhoai-connector/tasks.md` group 2 (RHIDP-15323): + +- 2.1 Define Zod config schema for `catalog.providers.rhoai.mcpCatalog` +- 2.2 Implement config validation in module startup +- 2.3 Implement enable/disable toggle +- 2.4 Implement K8s Secret loader utility +- 2.5 Integrate shared CA bundle utility from RHIDP-15316 +- 2.6 Implement Secret refresh on each `refresh()` cycle +- 2.7 Implement CA bundle fallback to system CA +- 2.8 Add startup logging: enabled/disabled status, endpoint URL, Secret ref +- 2.9 Add error logging for missing/invalid config without crashing + +### Specifications + +- `openspec/changes/rhoai-connector/specs/deployment-config/spec.md` + +--- + +## Neo4j Knowledge Graph — Core Sync Adapter (issue 17 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 2 (SDK interfaces — `Neo4jSyncAdapter`) +**RHIDP Stories:** RHIDP-15299 +**Feature:** RHDHPLAN-1507 — Epic RHIDP-15295 + +Implement the Neo4j sync adapter: Neo4j driver factory, catalog API polling with AI asset annotation filtering, entity revision tracking, incremental sync logic, scheduled sync task, graph node creation for Skill/Tool/Domain/Agent/ModelServer types, relationship mapping (DEPENDS_ON, USES_TOOL, BELONGS_TO, SIMILAR_TO, IMPLEMENTED_BY), and SDK interface implementation (`createNeo4jSyncAdapter()` factory, `connect()`/`disconnect()` lifecycle, `triggerFullSync()`). + +### Tasks + +From `openspec/changes/neo4j-knowledge-graph/tasks.md` group 1 (RHIDP-15299): + +- 1.1 Create backend plugin package at `workspaces/boost/plugins/catalog-backend-module-neo4j-sync/` +- 1.2 Implement Neo4j driver factory with configuration loading +- 1.3 Implement catalog API polling with entity filtering +- 1.4 Implement entity revision tracking using `_syncedRevision` +- 1.5 Implement incremental sync logic +- 1.6 Implement scheduled sync task +- 1.7 Implement sync failure isolation +- 1.8 Implement full sync trigger API endpoint + +From `openspec/changes/neo4j-knowledge-graph/tasks.md` group 2 (RHIDP-15299): + +- 2.1 Implement Skill node creation +- 2.2 Implement Tool node creation +- 2.3 Implement Domain node creation +- 2.4 Implement Agent node creation +- 2.5 Implement ModelServer node creation +- 2.6 Implement node update logic +- 2.7 Implement node deletion logic + +From `openspec/changes/neo4j-knowledge-graph/tasks.md` group 3 (RHIDP-15299): + +- 3.1 Implement DEPENDS_ON relationship creation +- 3.2 Implement USES_TOOL relationship creation +- 3.3 Implement BELONGS_TO relationship creation +- 3.4 Implement SIMILAR_TO relationship creation with Jaccard similarity +- 3.5 Implement IMPLEMENTED_BY relationship creation +- 3.6 Implement relationship deletion logic +- 3.7 Implement deferred relationship creation + +From `openspec/changes/neo4j-knowledge-graph/tasks.md` group 5 (RHIDP-15299): + +- 5.1 Implement `createNeo4jSyncAdapter()` factory function +- 5.2 Implement `connect()` lifecycle hook +- 5.3 Implement `disconnect()` lifecycle hook +- 5.4 Implement `startSync()` method +- 5.5 Implement `stopSync()` method +- 5.6 Implement `triggerFullSync()` with `SyncReport` return type +- 5.7 Validate configuration via `config.getConfig('aiCatalog.neo4j')` + +### Specifications + +- `openspec/changes/neo4j-knowledge-graph/specs/relationship-mapping/spec.md` + +--- + +## Neo4j — SkillBundle Support (issue 18 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 17 (core sync adapter) +**RHIDP Stories:** RHIDP-15300 +**Feature:** RHDHPLAN-1507 — Epic RHIDP-15295 + +Add SkillBundle node creation with INCLUDES relationships linking bundles to their constituent skills, bundle update propagation, deletion cleanup, and metadata validation. + +### Tasks + +From `openspec/changes/neo4j-knowledge-graph/tasks.md` group 4 (RHIDP-15300): + +- 4.1 Implement SkillBundle node creation with properties +- 4.2 Implement INCLUDES relationship creation from `spec.skills` list +- 4.3 Implement SkillBundle update propagation +- 4.4 Implement SkillBundle deletion cleanup +- 4.5 Implement SkillBundle metadata validation +- 4.6 Add bundle composition example queries to `examples/neo4j-queries.cypher` + +### Specifications + +- `openspec/changes/neo4j-knowledge-graph/specs/skill-bundles/spec.md` + +--- + +## Neo4j — Setup Documentation and Observability (issue 19 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 17 (core sync adapter), Issue 18 (SkillBundle support) +**RHIDP Stories:** RHIDP-15301 +**Feature:** RHDHPLAN-1507 — Epic RHIDP-15295 + +Write setup documentation (configuration examples, K8s Secret setup, graph schema reference, example Cypher queries), implement Prometheus metrics export (`neo4j_sync_total`, `neo4j_sync_success`, etc.), and add structured logging for sync cycles. Includes testing and performance optimization (batch writes, similarity throttling). + +### Tasks + +From `openspec/changes/neo4j-knowledge-graph/tasks.md` group 6 (RHIDP-15301): + +- 6.1 Write `neo4j-sync-setup.md` with configuration examples +- 6.2 Document K8s Secret setup for Neo4j credentials +- 6.3 Document manual sync trigger API usage +- 6.4 Write `neo4j-graph-schema.md` with node/relationship type tables +- 6.5 Document catalog-as-source-of-truth architecture +- 6.6 Document relationship derivation rules +- 6.7 Write `examples/neo4j-queries.cypher` with 5+ example queries + +From `openspec/changes/neo4j-knowledge-graph/tasks.md` group 7 (RHIDP-15301): + +- 7.1 Document sync failure troubleshooting steps +- 7.2 Document Neo4j connection troubleshooting +- 7.3 Document schema migration procedure +- 7.4 Implement Prometheus metrics export +- 7.5 Document Prometheus metrics and example Grafana queries +- 7.6 Add structured logging for sync cycles + +From `openspec/changes/neo4j-knowledge-graph/tasks.md` groups 8–9: + +- 8.1–8.7 Testing (revision tracking, relationship derivation, in-memory Neo4j, SkillBundle, Cypher queries, full sync rebuild, failure isolation) +- 9.1–9.6 Performance optimization (batch writes, similarity throttling, similarity threshold config, disable flag, profiling, performance tuning docs) + +### Specifications + +- `openspec/changes/neo4j-knowledge-graph/specs/setup-documentation/spec.md` + +--- + +## Version-Level Policy Cascade and Default-Deny Configuration (issue 20 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 3 (permission definitions) +**RHIDP Stories:** RHIDP-15275, RHIDP-15306 (implementation) +**Feature:** RHDHPLAN-1508 — Epics RHIDP-15274, RHIDP-15270 + +Create `AICatalogRBACProvider` implementing the `RBACProvider` interface via `rbacProviderExtensionPoint`, with asset→version policy cascade propagation, event-driven `refresh()` with debouncing, and `policyDecisionPrecedence` config for version-specific override ordering. Implement default-deny configuration with global, per-category, and per-connector posture scoping, `rhdh.io/ai-catalog-ingested-at` annotation stamping, and startup validation. + +### Tasks + +From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 5 (RHIDP-15274, RHIDP-15275): + +- 5.1 Create `AICatalogRBACProvider` implementing `RBACProvider` interface +- 5.2 Register provider via `rbacProviderExtensionPoint` +- 5.3 Implement asset→version relationship discovery +- 5.4 Implement `applyConditionalPermissions()` propagation from asset to version entities +- 5.5 Implement event-driven `refresh()` with debouncing +- 5.6 Handle edge cases: orphan versions, asset deletion, no-version assets +- 5.7 Support `policyDecisionPrecedence` config for version-specific override ordering +- 5.8 Add unit tests for cascade propagation, override precedence, and edge cases + +From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 6 (RHIDP-15306): + +- 6.1 Add `ai-catalog.rbac.defaultPolicy` config schema (allow|deny, default: allow) +- 6.2 Add per-category config schema +- 6.3 Add per-connector config schema +- 6.4 Implement catch-all DENY conditional rule for deny-posture entities +- 6.5 Implement `rhdh.io/ai-catalog-ingested-at` annotation stamping at ingestion time +- 6.6 Implement configuration validation at startup +- 6.7 Add unit tests for default-deny posture + +### Specifications + +- `openspec/changes/ai-catalog-asset-governance/specs/version-policy-cascade/spec.md` +- `openspec/changes/ai-catalog-asset-governance/specs/default-deny-config/spec.md` + +--- + +## RBAC Audit Logging (issue 21 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 3 (permission definitions) +**RHIDP Stories:** RHIDP-15279, RHIDP-15280 +**Feature:** RHDHPLAN-1508 — Epic RHIDP-15277 + +Implement audit event infrastructure: define posture-change and policy CRUD event types, define ingestion sync events (start/success/failure), integrate with RHDH audit log channel, add config change tracking with actor identification and before/after capture, and implement disconnected cluster support with local audit log fallback and event queuing. + +### Tasks + +From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 7 (RHIDP-15277, RHIDP-15279, RHIDP-15280): + +- 7.1 Define audit event types: `posture-changed`, `policy-created`, `policy-updated`, `policy-deleted` (RHIDP-15279) +- 7.2 Define ingestion audit events: `sync-completed`, `sync-error`, `entity-created`, `entity-updated`, `entity-deleted` (RHIDP-15280) +- 7.3 Implement audit event emitters using `LoggerService` with structured metadata +- 7.4 Integrate audit events into posture change and policy CRUD flows +- 7.5 Integrate audit events into entity provider sync cycle +- 7.6 Verify events do not duplicate RBAC plugin `AuditorService` coverage + +From `openspec/changes/ingestion-audit-metrics/tasks.md` groups 1–4: + +Group 1 (Audit Event Infrastructure): + +- 1.1–1.8 Define ingestion audit event types, payload schema, emission helpers, RHDH audit log integration, serialization, validation, unit tests + +Group 2 (Sync Audit Integration): + +- 2.1–2.10 Lifecycle hooks (`onSyncStart`, `onSyncSuccess`, `onSyncFailure`), event emission, connector integration, asset count tracking, error serialization, integration tests + +Group 3 (Config Change Audit): + +- 3.1–3.6 Config change tracking, event emission, actor capture, before/after values, field serialization, integration tests + +Group 4 (Disconnected Cluster Support): + +- 4.1–4.5 Local audit log fallback, event queuing, file system persistence, replay mechanism, unit tests + +### Specifications + +- `openspec/changes/ai-catalog-asset-governance/specs/audit-logging/spec.md` +- `openspec/changes/ingestion-audit-metrics/specs/audit-events/spec.md` + +--- + +## Hot-Reload Propagation to Active Connectors (issue 22 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 6 (Zod schemas, RuntimeConfigResolver) +**RHIDP Stories:** RHIDP-15341 +**Feature:** RHDHPLAN-1513 — Epic RHIDP-15332 + +Update Jira, GitHub, and GitLab entity providers to read config via `RuntimeConfigResolver.getConfig()` at each reconciliation cycle start, implementing enable/disable check, endpoint URL propagation, schedule change propagation (reschedule task), credential re-read from mounted Secret per cycle, and config change logging. + +### Tasks + +From `openspec/changes/connector-config-hot-reload/tasks.md` group 3 (RHIDP-15341): + +- 3.1 Update Jira entity provider to read config via `RuntimeConfigResolver.getConfig('connectors.jira')` at reconciliation cycle start +- 3.2 Implement enable/disable check: skip sync if `enabled: false` +- 3.3 Implement endpoint URL propagation +- 3.4 Implement schedule change propagation: reschedule task +- 3.5 Update GitHub entity provider with same hot-reload pattern +- 3.6 Update GitLab entity provider with same hot-reload pattern +- 3.7 Add config change logging: log old → new values +- 3.8 Implement credential re-read: provider reads mounted Secret file at each cycle start +- 3.9–3.11 Integration tests: disable connector, change endpoint, change schedule +- 3.12 Document propagation latency: 30s TTL + reconciliation interval + +From `openspec/changes/connector-config-hot-reload/tasks.md` group 5 (RHIDP-15341): + +- 5.1 Integration test: update K8s Secret content, wait for kubelet sync, verify new credentials +- 5.2 Document credential rotation latency +- 5.3 Add manual test procedure: emergency credential rotation with pod restart + +### Specifications + +- `openspec/changes/connector-config-hot-reload/specs/hot-reload-propagation/spec.md` + +--- + +# Tier 2 — Depends on Tier 1 (7 issues) + +--- + +## SkillBundle RBAC Filtering (issue 23 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 3 (permission definitions) +**RHIDP Stories:** RHIDP-15310 +**Feature:** RHDHPLAN-1508 — Epic RHIDP-15270 + +Implement backend skill filtering using batch `authorizeConditional()` for `ai-catalog.asset.read`, add `totalSkills`/`visibleSkills` fields to SkillBundle API response, ensure filtered-out skill references are not exposed, and implement frontend "N of M skills visible" count display with restricted-access placeholder for fully restricted bundles. + +### Tasks + +From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 9 (RHIDP-15310, RHIDP-15273): + +- 9.1 Implement backend skill filtering using batch `authorizeConditional()` +- 9.2 Add `totalSkills` and `visibleSkills` fields to SkillBundle API response +- 9.3 Ensure filtered-out skill references are not exposed +- 9.4 Implement frontend "N of M skills visible" count display with tooltip +- 9.5 Implement restricted-access placeholder for fully restricted bundles +- 9.6 Suppress additional messaging when all skills are visible +- 9.7 Add unit tests for backend skill filtering + +### Specifications + +- `openspec/changes/ai-catalog-asset-governance/specs/skillbundle-filtering/spec.md` + +--- + +## Graduated Visibility — Frontend (issue 24 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 3 (permission definitions) +**RHIDP Stories:** RHIDP-15273 +**Feature:** RHDHPLAN-1508 — Epic RHIDP-15270 +**Cross-feature dependency:** RHIDP-15273 depends on RHIDP-15167 (RHDHPLAN-1509 — Entity page extensions). Graduated visibility wraps RHIDP-15167's entity page components with `RequirePermission` gating. Cannot gate what hasn't been built yet. + +Wrap Tier 2 sections in asset detail page with ``, create restricted-access placeholder for denied fields, implement filtered counts on asset list page, and add `usePermission` hook check for `ai-catalog.admin` to show/hide admin links. + +### Tasks + +From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 3 (RHIDP-15273): + +- 3.1 Wrap Tier 2 sections in asset detail page with `` +- 3.2 Create restricted-access placeholder component for denied Tier 2 sections +- 3.3 Ensure asset list page displays filtered counts matching backend-filtered results +- 3.4 Add `usePermission` hook check for `ai-catalog.admin` to show/hide admin links + +### Specifications + +- `openspec/changes/ai-catalog-asset-governance/specs/graduated-visibility/spec.md` + +--- + +## RBAC Admin UI — Dashboard, Policy Editor, Default Posture (issue 25 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 3 (permission definitions), Issue 20 (policy cascade + default-deny backend) +**RHIDP Stories:** RHIDP-15307, RHIDP-15308, RHIDP-15309 +**Feature:** RHDHPLAN-1508 — Epic RHIDP-15304 + +Create standalone page at `/ai-catalog/admin/rbac` with `RequirePermission` gating, implement current policies view fetching from RBAC REST API, policy creation/deletion forms with confirmation dialogs, default posture view and change controls, and sidebar navigation item with permission-based visibility. + +### Tasks + +From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 8 (RHIDP-15304, RHIDP-15307, RHIDP-15308, RHIDP-15309): + +- 8.1 Create standalone page component at `/ai-catalog/admin/rbac` with `RequirePermission` gating (RHIDP-15307) +- 8.2 Implement current policies view from RBAC REST API (RHIDP-15307) +- 8.3 Implement policy creation form (RHIDP-15308) +- 8.4 Implement policy deletion with confirmation dialog (RHIDP-15308) +- 8.5 Implement default posture view and change controls (RHIDP-15309) +- 8.6 Add sidebar navigation item with `usePermission` visibility gating (RHIDP-15307) +- 8.7 Add error handling for RBAC REST API failures + +### Specifications + +- `openspec/changes/ai-catalog-asset-governance/specs/rbac-admin-ui/spec.md` +- `openspec/changes/ai-catalog-asset-governance/specs/default-deny-config/spec.md` + +--- + +## Ingestion Health Admin UI and Disconnected-Cluster View (issue 26 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 5 (health API, error classification) +**RHIDP Stories:** RHIDP-15336, RHIDP-15339 +**Feature:** RHDHPLAN-1513 — Epic RHIDP-15331 + +Implement `IngestionHealthPanel.tsx` with per-connector health cards (PatternFly Card/Label), status badges (healthy/degraded/failing/disabled), timestamps, error summaries with diagnostic guidance, "Force Sync" buttons, disabled connector visual treatment (grey badge, no error indicators), disconnected-cluster differentiation, and health data polling via `useSWR` with 30s refresh. Includes Force Sync backend routes and connector provider integration. + +### Tasks + +From `openspec/changes/ingestion-health-dashboard/tasks.md` group 4 (RHIDP-15336, RHIDP-15339): + +- 4.1 Create `IngestionHealthPanel.tsx` component +- 4.2 Implement health card rendering with PatternFly components +- 4.3 Add status badge rendering (success/warning/danger/outline variants) +- 4.4 Add timestamp rendering with `react-time-ago` +- 4.5 Add sync metrics display +- 4.6 Add error summary section with diagnostic guidance +- 4.7 Add "Force Sync" button with disabled state during run +- 4.8 Implement disabled connector visual treatment (RHIDP-15339) +- 4.9 Add loading state +- 4.10 Add error state +- 4.11 Add empty state +- 4.12 Implement health data polling via `useSWR` with 30s refresh +- 4.13 Add responsive grid layout (PatternFly `Gallery`) + +From `openspec/changes/ingestion-health-dashboard/tasks.md` group 6 (RHIDP-15335, RHIDP-15336): + +- 6.1 Implement `POST /api/boost/ingestion-health/:connectorId/force-sync` route +- 6.2 Add connector run state registry +- 6.3 Implement concurrent Force Sync prevention (409 if already running) +- 6.4 Implement Force Sync trigger +- 6.5 Add Force Sync timeout wrapper +- 6.6 Implement status polling route +- 6.7 Add Force Sync UI polling +- 6.8 Add Force Sync error handling in UI +- 6.9 Add Force Sync integration tests + +From `openspec/changes/ingestion-health-dashboard/tasks.md` group 7: + +- 7.1–7.6 Connector provider integration (health tracking hooks in GitHub/GitLab/Jira providers, sync metrics, error capture) + +From `openspec/changes/ingestion-health-dashboard/tasks.md` group 8: + +- 8.1–8.4 Navigation integration (sidebar item, route, active state highlighting, pattern consistency) + +### Specifications + +- `openspec/changes/ingestion-health-dashboard/specs/admin-health-ui/spec.md` + +--- + +## Neo4j Graph Sync Status Panel (issue 27 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 5 (health API), Issue 17 (Neo4j core sync adapter) +**RHIDP Stories:** RHIDP-15338 +**Feature:** RHDHPLAN-1513 — Epic RHIDP-15331 + +Add Neo4j sync status panel within the ingestion health admin dashboard: sync timestamps, outcome badge, node/relationship counts, "Force Re-sync" button with Full/Incremental toggle (PatternFly `ToggleGroup`), backend routes for Neo4j health status and force sync, and Neo4j sync adapter health tracking hook integration. + +### Tasks + +From `openspec/changes/ingestion-health-dashboard/tasks.md` group 5 (RHIDP-15338): + +- 5.1 Implement `GET /api/boost/ingestion-health/neo4j` route returning Neo4j sync status +- 5.2 Add Neo4j panel rendering in `IngestionHealthPanel.tsx` below connector cards +- 5.3 Add Neo4j panel header with "Knowledge Graph Sync" title and graph icon +- 5.4 Add sync status display (last sync timestamp, outcome badge, node count, relationship count) +- 5.5 Add "Force Re-sync" button with mode toggle (Full/Incremental) +- 5.6 Implement `POST /api/boost/ingestion-health/neo4j/force-sync` route with mode parameter +- 5.7 Add Neo4j panel error state +- 5.8 Add Neo4j panel loading state +- 5.9 Integrate Neo4j sync adapter health tracking hooks + +### Specifications + +- `openspec/changes/ingestion-health-dashboard/specs/admin-health-ui/spec.md` + +--- + +## Connector Config Admin UI (issue 28 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 6 (Zod schemas), Issue 22 (hot-reload propagation) +**RHIDP Stories:** RHIDP-15342 +**Feature:** RHDHPLAN-1513 — Epic RHIDP-15332 + +Create connector config section in admin panel at `/admin/connectors` with toggle switches for enable/disable, form fields for endpoint URL and sync schedule, read-only K8s Secret reference display, client-side and server-side Zod validation, RBAC gating, and config change history view from audit log. + +### Tasks + +From `openspec/changes/connector-config-hot-reload/tasks.md` group 4 (RHIDP-15342): + +- 4.1 Create connector config section in admin panel (`/admin/connectors`) +- 4.2 Implement connector list view with toggle switches for `enabled` state +- 4.3 Implement connector detail view with form fields +- 4.4 Display K8s Secret references as read-only fields with tooltip +- 4.5 Implement client-side validation +- 4.6 Implement save handler: call `POST /api/boost/admin/config` +- 4.7 Implement success notification with propagation latency note +- 4.8 Implement validation error feedback +- 4.9 Implement RBAC gating +- 4.10 Implement read-only view for non-admin users +- 4.11 Implement config change history view +- 4.12–4.13 UI tests + +From `openspec/changes/connector-config-hot-reload/tasks.md` group 6: + +- 6.1 Add connector config endpoints to `AdminConfigService` backend API +- 6.2 Implement Zod schema validation in `setConfig()` before DB write +- 6.3 Implement `configScope` enforcement +- 6.4 Implement cache invalidation call +- 6.5 Add audit logging for connector config changes +- 6.6 Add unit tests for `AdminConfigService` connector config methods + +### Specifications + +- `openspec/changes/connector-config-hot-reload/specs/config-admin-ui/spec.md` + +--- + +## Ingestion Analytics API and Eval Hub Integration (issue 29 of 29) + +_GitHub issue not yet created_ + +**Labels:** `ready-to-code` +**Depends on:** Issue 5 (health data model), Issue 21 (audit logging) +**RHIDP Stories:** RHIDP-15280 (analytics scope) +**Feature:** RHDHPLAN-1508 — Epic RHIDP-15277 (consolidated from RHDHPLAN-1513 RHIDP-15333) + +Implement analytics REST API endpoints (sync history, quality scores, match coverage) with RBAC gating and pagination, quality score storage (DB table + store), match coverage calculator, Neo4j sync status embedding, Eval Hub client for external quality score ingestion, and multi-eval backend support (LightEval, IBM Clear, GuideLLM). + +### Tasks + +From `openspec/changes/ingestion-audit-metrics/tasks.md` group 5 (RHIDP-15344): + +- 5.1 Define analytics API routes +- 5.2 Add `GET /api/boost/admin/analytics/sync-history` endpoint +- 5.3 Add `GET /api/boost/admin/analytics/quality-scores` endpoint +- 5.4 Add `GET /api/boost/admin/analytics/match-coverage` endpoint +- 5.5 Add RBAC gating to all endpoints +- 5.6–5.10 Pagination, date range filtering, connector filtering, eval source filtering, route registration +- 5.11 Add integration tests + +From `openspec/changes/ingestion-audit-metrics/tasks.md` group 6: + +- 6.1–6.7 Sync history service: `AnalyticsService`, `getSyncHistory()`, pagination, date range filtering, connector filtering, duration calculation, unit tests + +From `openspec/changes/ingestion-audit-metrics/tasks.md` group 7: + +- 7.1–7.8 Quality score storage: DB table schema, migration, `QualityScoresStore`, `insertScore()`, `getScoresBySkill()`, `getLatestScores()`, indexes, unit tests + +From `openspec/changes/ingestion-audit-metrics/tasks.md` group 8: + +- 8.1–8.6 Quality score analytics: `getQualityScores()`, per-skill scores, aggregate distribution, normalization, eval source filtering, unit tests + +From `openspec/changes/ingestion-audit-metrics/tasks.md` group 9: + +- 9.1–9.8 Match coverage calculator: agent capability extraction, skill ID extraction, matching logic, coverage ratio, unmatched capabilities list, caching, unit tests + +From `openspec/changes/ingestion-audit-metrics/tasks.md` group 10: + +- 10.1–10.6 Neo4j sync status: connection check, last sync timestamp, entity count, embed in analytics responses, graceful unavailable handling, unit tests + +From `openspec/changes/ingestion-audit-metrics/tasks.md` group 11: + +- 11.1–11.8 Eval Hub client: interface, `fetchQualityScores()`, app-config schema, client init, HTTP client, error handling, score normalization, unit tests + +From `openspec/changes/ingestion-audit-metrics/tasks.md` group 12: + +- 12.1–12.8 Eval Hub ingestion service: background task, refresh interval config, score fetching/storage, graceful unavailable handling, manual trigger endpoint, status logging, integration tests + +From `openspec/changes/ingestion-audit-metrics/tasks.md` group 13: + +- 13.1–13.6 Multi-eval backend support: `eval_source` field, source normalization, source filtering, per-source aggregation, LightEval/IBM Clear/GuideLLM support, unit tests + +### Specifications + +- `openspec/changes/ingestion-audit-metrics/specs/analytics-api/spec.md` +- `openspec/changes/ingestion-audit-metrics/specs/eval-hub-integration/spec.md` + +--- + +# Dependency Graph + +``` +Tier 0 (no dependencies — all parallel): + [1] Cross-Connector Shared Infrastructure + [2] Entity-Provider SDK Types & Interfaces + [3] AI Catalog Permissions & Conditional Rules + [4] Upstream Schema Alignment + [5] Ingestion Health API & Error Classification + [6] Connector Config Zod Schemas + [7] MCP Mirror Endpoint + RHOAI Version Normalization + +Tier 1 (depends on Tier 0): + [8] SDK Delta Sync + Publish → [1], [2] + [9] OCI Core Connector → [1], [8] + [10] OCI Multi-Registry + Air-Gapped → [1], [9] + [11] OCI Digest-Based Sync → [1], [9] + [12] OCI Load Testing → [1], [9] + [13] MCP TLS + Credential Hardening → [1], [7] + [14] MCP Annotation Enrichment → [8], [13] + [15] RHOAI MCP Catalog Source → [8] + [16] RHOAI Deployment Config → [1], [15] + [17] Neo4j Core Sync Adapter → [2] + [18] Neo4j SkillBundle Support → [17] + [19] Neo4j Docs + Observability → [17], [18] + [20] Version Policy Cascade + Default-Deny → [3] + [21] RBAC Audit Logging → [3] + [22] Hot-Reload Propagation → [6] + +Tier 2 (depends on Tier 1): + [23] SkillBundle RBAC Filtering → [3] + [24] Graduated Visibility Frontend → [3], RHIDP-15167 (RHDHPLAN-1509) + [25] RBAC Admin UI → [3], [20] + [26] Ingestion Health Admin UI → [5] + [27] Neo4j Sync Status Panel → [5], [17] + [28] Connector Config Admin UI → [6], [22] + [29] Analytics API + Eval Hub → [5], [21] +``` From 232b7e29e803eba5af3044c72995e97ce1dfd9e5 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Mon, 20 Jul 2026 16:35:32 -0400 Subject: [PATCH 10/18] docs(boost): RHDHPLAN-1513 deferral impact analysis on 2.1 staging Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- ...-defer-from-2-1-staging-and-jira-impact.md | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1513-defer-from-2-1-staging-and-jira-impact.md diff --git a/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1513-defer-from-2-1-staging-and-jira-impact.md b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1513-defer-from-2-1-staging-and-jira-impact.md new file mode 100644 index 0000000000..2c0ae85dfe --- /dev/null +++ b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1513-defer-from-2-1-staging-and-jira-impact.md @@ -0,0 +1,130 @@ +# RHDHPLAN-1513 — Deferral Impact on 2.1 Staging and Jira + +## Context + +RHDHPLAN-1513 (Ingestion Operations & Schema Alignment) may be deferred from the 2.1 release. This document analyzes the impact on the staged GitHub issues in `rhdhplan1505-1-staged-issues.md` (29 issues across 3 dependency tiers covering RHDHPLAN-1507, 1508, 1510, and 1513). + +## RHDHPLAN-1513 Epics + +| Epic | Name | +| ----------- | ---------------- | +| RHIDP-15331 | Health Dashboard | +| RHIDP-15332 | Hot-Reload | +| RHIDP-15334 | Schema Alignment | + +Note: RHIDP-15333 (Ingestion Audit Metrics) was originally a 1513 epic but was consolidated into RHDHPLAN-1508 Epic RHIDP-15277. Its stories (Issue 29) are now 1508-owned. + +## Story-Level Analysis by Epic + +### Epic RHIDP-15331 (Health Dashboard) — 5 stories + +| RHIDP Story | Description | Start Issue | Start Tier | Complete Issue | Complete Tier | +| ----------- | ------------------------- | ----------- | ---------- | -------------- | ------------- | +| RHIDP-15335 | Health API + Data Model | Issue 5 | Tier 0 | Issue 26 | Tier 2 | +| RHIDP-15337 | Error Classification | Issue 5 | Tier 0 | Issue 5 | Tier 0 | +| RHIDP-15336 | Admin Health UI | Issue 26 | Tier 2 | Issue 26 | Tier 2 | +| RHIDP-15338 | Neo4j Sync Status Panel | Issue 27 | Tier 2 | Issue 27 | Tier 2 | +| RHIDP-15339 | Disconnected Cluster View | Issue 26 | Tier 2 | Issue 26 | Tier 2 | + +RHIDP-15335 is the only multi-issue split in this epic: the health API and data model are defined in Issue 5 (Tier 0), but the force-sync backend routes consuming that data are in Issue 26 (Tier 2, task group 6 tagged `RHIDP-15335, RHIDP-15336`). + +### Epic RHIDP-15332 (Hot-Reload) — 3 stories + +| RHIDP Story | Description | Start Issue | Start Tier | Complete Issue | Complete Tier | +| ----------- | ------------------------------------------ | ----------- | ---------- | -------------- | ------------- | +| RHIDP-15340 | Zod Config Schemas + RuntimeConfigResolver | Issue 6 | Tier 0 | Issue 6 | Tier 0 | +| RHIDP-15341 | Hot-Reload Propagation to Connectors | Issue 22 | Tier 1 | Issue 22 | Tier 1 | +| RHIDP-15342 | Connector Config Admin UI | Issue 28 | Tier 2 | Issue 28 | Tier 2 | + +No multi-issue splits. Each story completes in a single issue. The entire Hot-Reload epic is a clean, isolated vertical — nothing outside of 1513 depends on Issue 6 or its downstream chain (Issues 22, 28). + +### Epic RHIDP-15334 (Schema Alignment) — 2 stories (1513-owned) + +| RHIDP Story | Description | Start Issue | Start Tier | Complete Issue | Complete Tier | +| ----------- | -------------------------------- | ----------- | ---------- | -------------- | ------------- | +| RHIDP-15346 | Annotation Specification Mapping | Issue 4 | Tier 0 | Issue 4 | Tier 0 | +| RHIDP-15347 | Migration Readiness CLI | Issue 4 | Tier 0 | Issue 4 | Tier 0 | + +Note: RHIDP-15302 (Migration Design Document) is also in Issue 4 but belongs to **RHDHPLAN-1507** Epic RHIDP-15258, not 1513. If 1513 is deferred, Issue 4 must be split — RHIDP-15302 stays, RHIDP-15346/15347 defer. + +## 1513 Footprint Across Tiers + +| Tier | 1513 Issues | Issue Count | Share of Tier | +| --------- | ----------------- | ----------- | ------------- | +| Tier 0 | Issues 4, 5, 6 | 3 of 7 | 43% | +| Tier 1 | Issue 22 | 1 of 15 | 7% | +| Tier 2 | Issues 26, 27, 28 | 3 of 7 | 43% | +| **Total** | | **7 of 29** | **24%** | + +## Cross-Feature Entanglements + +Three entanglements exist between 1513 issues and other features: + +### 1. Issue 4 is shared with RHDHPLAN-1507 + +Issue 4 bundles RHIDP-15302 (Migration Design, 1507) with RHIDP-15346/15347 (Schema Alignment, 1513). Deferring 1513 requires splitting Issue 4 so that RHIDP-15302 can proceed independently. + +### 2. Issue 29 (RHDHPLAN-1508) depends on Issue 5 (1513) + +Issue 29 (Ingestion Analytics API, RHIDP-15280) is owned by RHDHPLAN-1508 but depends on Issue 5's health data model (RHIDP-15335, 1513). Deferring 1513 blocks Issue 29 unless it is also deferred or re-scoped to remove the health data dependency. + +### 3. RHDHPLAN-1509 depends on Issue 5 (1513) + +Per the cross-feature dependencies in the staging document, RHIDP-15167 (Entity page extensions, RHDHPLAN-1509) depends on RHIDP-15335 (Issue 5, 1513). Deferring 1513 breaks this chain unless RHDHPLAN-1509 is re-sequenced to not depend on the health API. + +## Issues Safe to Run While Decision Is Pending + +The 1513 decision does not block most of the staged work. Only issues whose dependency chain touches Issues 4, 5, or 6 are blocked. Everything else can proceed. + +**Tier 0 (4 of 7):** + +| Issue | Feature | Description | +| ------- | ------------- | -------------------------------------------------------------- | +| Issue 1 | RHDHPLAN-1510 | Cross-Connector Shared Infrastructure Package | +| Issue 2 | RHDHPLAN-1507 | Entity-Provider SDK — Types, Interfaces, Annotation Validation | +| Issue 3 | RHDHPLAN-1508 | AI Catalog Permissions, Backend Enforcement, Conditional Rules | +| Issue 7 | RHDHPLAN-1510 | MCP Mirror Endpoint + RHOAI Version Normalization | + +**Tier 1 (14 of 15) — all except Issue 22 (depends on Issue 6):** + +| Issue | Feature | Description | Depends On | +| -------- | ------------- | ------------------------------------- | ---------- | +| Issue 8 | RHDHPLAN-1507 | SDK Delta Sync + Publish | 1, 2 | +| Issue 9 | RHDHPLAN-1507 | OCI Core Connector | 1, 8 | +| Issue 10 | RHDHPLAN-1507 | OCI Multi-Registry + Air-Gapped | 1, 9 | +| Issue 11 | RHDHPLAN-1507 | OCI Digest-Based Sync | 1, 9 | +| Issue 12 | RHDHPLAN-1507 | OCI Load Testing | 1, 9 | +| Issue 13 | RHDHPLAN-1510 | MCP TLS + Credential Hardening | 1, 7 | +| Issue 14 | RHDHPLAN-1510 | MCP Annotation Enrichment | 8, 13 | +| Issue 15 | RHDHPLAN-1510 | RHOAI MCP Catalog Source | 8 | +| Issue 16 | RHDHPLAN-1510 | RHOAI Deployment Config | 1, 15 | +| Issue 17 | RHDHPLAN-1507 | Neo4j Core Sync Adapter | 2 | +| Issue 18 | RHDHPLAN-1507 | Neo4j SkillBundle Support | 17 | +| Issue 19 | RHDHPLAN-1507 | Neo4j Docs + Observability | 17, 18 | +| Issue 20 | RHDHPLAN-1508 | Version Policy Cascade + Default-Deny | 3 | +| Issue 21 | RHDHPLAN-1508 | RBAC Audit Logging | 3 | + +**Tier 2 (3 of 7):** + +| Issue | Feature | Description | Depends On | +| -------- | ------------- | ----------------------------- | ---------- | +| Issue 23 | RHDHPLAN-1508 | SkillBundle RBAC Filtering | 3 | +| Issue 24 | RHDHPLAN-1508 | Graduated Visibility Frontend | 3, 1509 | +| Issue 25 | RHDHPLAN-1508 | RBAC Admin UI | 3, 20 | + +**Total: 21 of 29 issues (72%) can proceed without the 1513 decision.** + +Issues blocked pending the decision (8 of 29): + +- **Issue 4** (Tier 0) — shared with 1507, needs splitting if deferred +- **Issue 5** (Tier 0) — cross-feature dependency from 1508 (Issue 29) and 1509 (RHIDP-15167) +- **Issue 6** (Tier 0) — pure 1513, isolated chain, but no reason to start if deferring +- **Issue 22** (Tier 1) — depends on Issue 6 +- **Issue 26** (Tier 2) — depends on Issue 5 +- **Issue 27** (Tier 2) — depends on Issues 5, 17 +- **Issue 28** (Tier 2) — depends on Issues 6, 22 +- **Issue 29** (Tier 2) — depends on Issues 5, 21 (1508-owned but health data dependency) + +## Decision Deadline + +The decision only becomes blocking **when the 1513-free work is exhausted** — i.e., when the 21 safe issues above are complete or in progress and the remaining 8 are next in line. Since this spans all three tiers, the natural buffer is substantial: the full duration of Tier 0 Issues 1, 2, 3, 7, then their Tier 1 and Tier 2 downstream chains. The decision does not need to be made before Tier 0 launches or even before Tier 1 begins. From 8bd6488bf5efc56550b9136e706f675418edd729 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Tue, 21 Jul 2026 13:48:36 -0400 Subject: [PATCH 11/18] fix(boost): RHDHPLAN-1505 align staging plan with openspec review changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Issue 2 task 1.1: add explicit 7-value enum list for rhdh.io/ai-asset-category - Issue 9 task 3.2: Resource → AIResource per RHDHPLAN-1113 resolution Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../JIRA-analysis/rhdhplan1505-1-staged-issues.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md index 09c03c85a1..ad5063fa58 100644 --- a/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md +++ b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md @@ -139,7 +139,7 @@ Create the `@boost/entity-provider-sdk` package with the AI Asset annotation sch From `openspec/changes/ai-catalog-entity-model/tasks.md` group 1 (RHIDP-15255): -- 1.1 Define `rhdh.io/ai-asset-category` annotation constant and allowed values enum +- 1.1 Define `rhdh.io/ai-asset-category` annotation constant and allowed values enum (`agent`, `skill`, `rule`, `skill-bundle`, `mcp-server`, `ai-model`, `model-server`) - 1.2 Define `rhdh.io/ai-asset-version` annotation constant - 1.3 Define `rhdh.io/ai-asset-source` annotation constant - 1.4 Implement `normalizeAIAssetVersion(sourceVersion)` utility with all four normalization rules @@ -511,7 +511,7 @@ From `openspec/changes/oci-skill-registry/tasks.md` group 2 (RHIDP-15296): From `openspec/changes/oci-skill-registry/tasks.md` group 3 (RHIDP-15296): - 3.1 Implement `OciSkillRegistryProvider` class extending `EntityProvider` interface -- 3.2 Implement entity factory: convert `skillcard.yaml` to Backstage `Resource` entity +- 3.2 Implement entity factory: convert `skillcard.yaml` to Backstage `AIResource` entity - 3.3 Populate required annotations: `rhdh.io/ai-asset-category`, `rhdh.io/ai-asset-version`, `rhdh.io/ai-asset-source` - 3.4 Implement entity ref sanitization - 3.5 Write unit tests for entity emission From eef4734a7c416d91a8c3d649722906a51edad4aa Mon Sep 17 00:00:00 2001 From: gabemontero Date: Fri, 24 Jul 2026 10:32:12 -0400 Subject: [PATCH 12/18] fix(boost): RHDHPLAN-1505 align staging plan with RHDHPLAN-1508 post-merge state - Feature mapping: remove closed RHIDP-15305 (absorbed into RHIDP-15270) - Issue 3: fix epic reference to RHIDP-15270 only - Issue 20: add task 6.8 (policy-change timestamp persistence) Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../JIRA-analysis/rhdhplan1505-1-staged-issues.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md index ad5063fa58..d7faec164a 100644 --- a/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md +++ b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md @@ -6,12 +6,12 @@ Each issue is scoped for a single fullsend `/fs-code` run. Frontend admin UI iss **Feature → Epic mapping:** -| Feature | Epics | -| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| RHDHPLAN-1507 | RHIDP-15258 (Entity Model), RHIDP-15294 (OCI Skill Registry), RHIDP-15295 (Neo4j Knowledge Graph) | -| RHDHPLAN-1508 | RHIDP-15270 (Graduated Visibility), RHIDP-15274 (Version Policy Cascade), RHIDP-15277 (Audit Logging), RHIDP-15304 (RBAC Admin UI), RHIDP-15305 (Conditional Rules) | -| RHDHPLAN-1510 | RHIDP-15313 (MCP Registry), RHIDP-15314 (RHOAI Connector), RHIDP-15316 (Cross-Connector Shared Infra) | -| RHDHPLAN-1513 | RHIDP-15331 (Health Dashboard), RHIDP-15332 (Hot-Reload), RHIDP-15334 (Schema Alignment) | +| Feature | Epics | +| ------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| RHDHPLAN-1507 | RHIDP-15258 (Entity Model), RHIDP-15294 (OCI Skill Registry), RHIDP-15295 (Neo4j Knowledge Graph) | +| RHDHPLAN-1508 | RHIDP-15270 (Graduated Visibility), RHIDP-15274 (Version Policy Cascade), RHIDP-15277 (Audit Logging), RHIDP-15304 (RBAC Admin UI) | +| RHDHPLAN-1510 | RHIDP-15313 (MCP Registry), RHIDP-15314 (RHOAI Connector), RHIDP-15316 (Cross-Connector Shared Infra) | +| RHDHPLAN-1513 | RHIDP-15331 (Health Dashboard), RHIDP-15332 (Hot-Reload), RHIDP-15334 (Schema Alignment) | **Cross-feature dependencies (RHDHPLAN-1509):** @@ -183,7 +183,7 @@ _GitHub issue not yet created_ **Labels:** `ready-to-code` **Dependencies:** None **RHIDP Stories:** RHIDP-15271, RHIDP-15272, RHIDP-15306 (permission definitions), RHIDP-15312 -**Feature:** RHDHPLAN-1508 — Epics RHIDP-15270, RHIDP-15305 +**Feature:** RHDHPLAN-1508 — Epic RHIDP-15270 Define AI Catalog permission constants (`ai-catalog.asset.read`, `ai-catalog.asset.read.usage-docs`, `ai-catalog.admin`), implement graduated visibility backend enforcement (Tier 1 entity-level + Tier 2 field-level filtering), and implement conditional permission rules (`isAiAssetCategory`, `isFromConnector`, `isInTenant`) with `toQuery()` support. The default-deny config implementation is in Issue 20. @@ -969,6 +969,7 @@ From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 6 (RHIDP-1530 - 6.5 Implement `rhdh.io/ai-catalog-ingested-at` annotation stamping at ingestion time - 6.6 Implement configuration validation at startup - 6.7 Add unit tests for default-deny posture +- 6.8 Persist policy-change timestamp (via `AdminConfigService.setOverride()`) when admin changes default posture; read in `AICatalogRBACProvider.refresh()` to compare against `rhdh.io/ai-catalog-ingested-at` ### Specifications From 5a278bfe8ce7a4a43062f06d88932e91035be9ea Mon Sep 17 00:00:00 2001 From: gabemontero Date: Mon, 27 Jul 2026 15:00:49 -0400 Subject: [PATCH 13/18] fix(boost): RHDHPLAN-1510 remove stale Model Registry/Kubeflow references from JIRA-analysis reports RHIDP-15320 (Model Registry source) was closed and moved to RHDHPLAN-404 scope. The feasibility report and frontend coverage doc still carried Kubeflow/Model Registry references predating that scope change. - feasibility: update RHIDP-15314 section to MCP-catalog-only (header, summary, AC table, verdict, implementation note, summary matrix) - feasibility: strike Model Registry client row in capabilities table - frontend-coverage: strike Model Registry browse row, update RHIDP-15314 bullet to remove Kubeflow reference Co-Authored-By: Claude Opus 4.6 --- .../RHDHPLAN-1510-feasibility-report.md | 38 +++++++++---------- .../RHDHPLAN-1510-frontend-coverage.md | 18 ++++----- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-feasibility-report.md b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-feasibility-report.md index 5716073093..057045be75 100644 --- a/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-feasibility-report.md +++ b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-feasibility-report.md @@ -27,7 +27,7 @@ RHDHPLAN-1510 is about connector implementations — entity providers that inges | Custom CA bundle handling | **Not built-in at catalog level** — standard Node.js/K8s TLS patterns | | K8s Secret credential injection | **Not built-in at catalog level** — standard `$env:`/`$secret:` app-config patterns | | OCI registry client | **Not built-in** — requires custom implementation or library | -| RHOAI/Kubeflow Model Registry client | **Not built-in** — requires custom implementation | +| ~~RHOAI/Kubeflow Model Registry client~~ | ~~**Not built-in** — requires custom implementation~~ _(RHDHPLAN-404 scope)_ | | MCP Registry mirror support | **Not built-in** — requires custom endpoint configuration | | Cross-connector fault isolation | **Not built-in** — each provider runs in its own bucket but shares the Node.js process | @@ -68,24 +68,24 @@ RHDHPLAN-1510 is about connector implementations — entity providers that inges --- -### RHIDP-15314: RHOAI Entity-Provider Connector (Model Registry + MCP Catalog) +### RHIDP-15314: RHOAI Entity-Provider Connector (MCP Catalog) -**Summary:** Entity provider with two toggleable sources: (1) RHOAI Model Registry API (`RegisteredModel`/`ModelVersion` → `ai-model`/`model-server`), (2) RHOAI 3.4 MCP catalog → `mcp-server`. Cross-cluster, K8s Secrets, custom CA. +**Summary:** Entity provider for the RHOAI 3.4 MCP catalog API → `mcp-server` entities. Cross-cluster, K8s Secrets, custom CA. _(Model Registry integration — Kubeflow API — is handled under RHDHPLAN-404, not this connector.)_ #### Acceptance Criteria Assessment -| Criterion | Feasible without upstream changes? | Assessment | -| ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Model Registry source connects to Kubeflow `RegisteredModel`/`ModelVersion` API, emits `ai-model`/`model-server` entities | **YES** | Standard entity provider implementation. The connector calls the Kubeflow Model Registry REST API, maps responses to Backstage entities (Resource with `spec.type: ai-model`, Component with `spec.type: model-server`), and emits via `applyMutation`. Prior art: `redhat-ai-dev/model-catalog-bridge` | -| RHOAI version normalization maps `ModelVersion` to `rhdh.io/ai-asset-version` | **YES** | Application-level mapping logic — extract version identifier from Kubeflow API response, set as annotation value | -| MCP catalog source connects to RHOAI 3.4 MCP catalog API, emits `mcp-server` entities | **YES** | Same pattern — REST API call, entity mapping, `applyMutation`. The RHOAI 3.4 MCP catalog API is a new RHOAI endpoint | -| MCP catalog source gracefully handles absence on earlier RHOAI versions | **YES** | Application-level — attempt API call, catch 404/connection error, log warning, disable MCP source for this cycle. Standard resilience pattern | -| Model Registry and MCP catalog sources independently toggleable | **YES** | App-config-driven: `catalog.providers.rhoai.modelRegistry.enabled: true/false` and `catalog.providers.rhoai.mcpCatalog.enabled: true/false`. Provider reads config at startup | -| Cross-cluster endpoint with K8s Secret credentials and custom CA bundles | **YES** | Standard patterns — configurable endpoint URL, `$env:` Secret references, CA bundle from mounted path. Shared utilities from RHIDP-15316 | +| Criterion | Feasible without upstream changes? | Assessment | +| ------------------------------------------------------------------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| ~~Model Registry source connects to Kubeflow `RegisteredModel`/`ModelVersion` API~~ | ~~YES~~ | ~~Kubeflow Model Registry~~ _(RHDHPLAN-404 scope — removed from RHIDP-15314)_ | +| RHOAI version normalization maps MCP server version to `rhdh.io/ai-asset-version` | **YES** | Application-level mapping logic — extract version identifier from MCP server manifest metadata, normalize via `normalizeAIAssetVersion()` | +| MCP catalog source connects to RHOAI 3.4 MCP catalog API, emits `mcp-server` entities | **YES** | Same pattern — REST API call, entity mapping, `applyMutation`. The RHOAI 3.4 MCP catalog API is a new RHOAI endpoint | +| MCP catalog source gracefully handles absence on earlier RHOAI versions | **YES** | Application-level — attempt API call, catch 404/connection error, log warning, disable MCP source for this cycle. Standard resilience pattern | +| MCP catalog source enable/disable toggle | **YES** | App-config-driven: `catalog.providers.rhoai.mcpCatalog.enabled: true/false`. Provider reads config at startup | +| Cross-cluster endpoint with K8s Secret credentials and custom CA bundles | **YES** | Standard patterns — configurable endpoint URL, `$env:` Secret references, CA bundle from mounted path. Shared utilities from RHIDP-15316 | -**Verdict: FULLY FEASIBLE** — This is a standard entity provider implementation against the Kubeflow Model Registry and RHOAI MCP catalog APIs. The Backstage `EntityProvider` interface handles everything needed. The `redhat-ai-dev/model-catalog-bridge` provides architectural prior art. No upstream Backstage changes needed. +**Verdict: FULLY FEASIBLE** — This is a standard entity provider implementation against the RHOAI MCP catalog API. The Backstage `EntityProvider` interface handles everything needed. No upstream Backstage changes needed. _(Model Registry integration is RHDHPLAN-404 scope.)_ -**Key implementation note:** Two independently toggleable sources can be implemented as either (a) two separate `EntityProvider` instances (simpler, each with its own bucket), or (b) a single provider that conditionally fetches from both sources and emits all entities in one `applyMutation`. Option (a) is cleaner — each source has its own isolated bucket and independent failure domains. +**Key implementation note:** Single-source MCP catalog provider implemented as one `EntityProvider` instance with its own isolated bucket. Graceful 404 handling enables compatibility with RHOAI versions that predate the MCP catalog API. **Dependency note (2026-07-13):** RHDHPLAN-404 will provide the new extended API entity schema that this connector leverages. RHIDP-15314 can proceed independently using Resource entities or a pre-merge version of the schema via the Catalog Model Layer. Additionally, RHDHPLAN-1510 / Boost will add a llamastack/OGX connector as an additional model information source. @@ -143,12 +143,12 @@ RHDHPLAN-1510 is about connector implementations — entity providers that inges ## Summary Matrix -| Epic | Key | Status | Feasible without upstream changes? | Implementation complexity | Notes | -| ------------------------------------- | ----------- | --------------------------------- | ---------------------------------- | ------------------------- | ---------------------------------------------------------------------- | -| MCP Registry — Productization | RHIDP-15313 | **Active** | **YES** | Low-Medium | Productization wrapper on upstream connector; depends on RHDHPLAN-393 | -| RHOAI Connector | RHIDP-15314 | **Active** | **YES** | Medium | Two-source provider against Kubeflow + RHOAI APIs; prior art exists | -| ~~OCI Skill Registry Connector~~ | RHIDP-15315 | **CLOSED** → absorbed by 15294 | YES | High | Overlap resolved — scope consolidated into RHIDP-15294 (RHDHPLAN-1507) | -| Cross-Connector Shared Infrastructure | RHIDP-15316 | **Active** (absorbed 15263 scope) | **YES** | Low-Medium | Now includes air-gapped patterns from RHIDP-15263 (RHDHPLAN-1507) | +| Epic | Key | Status | Feasible without upstream changes? | Implementation complexity | Notes | +| ------------------------------------- | ----------- | --------------------------------- | ---------------------------------- | ------------------------- | -------------------------------------------------------------------------- | +| MCP Registry — Productization | RHIDP-15313 | **Active** | **YES** | Low-Medium | Productization wrapper on upstream connector; depends on RHDHPLAN-393 | +| RHOAI Connector | RHIDP-15314 | **Active** | **YES** | Medium | MCP catalog provider against RHOAI 3.4 API; Model Registry is RHDHPLAN-404 | +| ~~OCI Skill Registry Connector~~ | RHIDP-15315 | **CLOSED** → absorbed by 15294 | YES | High | Overlap resolved — scope consolidated into RHIDP-15294 (RHDHPLAN-1507) | +| Cross-Connector Shared Infrastructure | RHIDP-15316 | **Active** (absorbed 15263 scope) | **YES** | Low-Medium | Now includes air-gapped patterns from RHIDP-15263 (RHDHPLAN-1507) | ## Key Findings diff --git a/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-frontend-coverage.md b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-frontend-coverage.md index cd719c0a9f..7414dd4d9e 100644 --- a/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-frontend-coverage.md +++ b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-frontend-coverage.md @@ -47,14 +47,14 @@ RHDHPLAN-1510's feature description explicitly states frontend dependencies on R All user-facing display of entities produced by RHDHPLAN-1510 connectors is delivered by RHDHPLAN-1509: -| RHDHPLAN-1510 Goal (frontend aspect) | RHDHPLAN-1509 Coverage | Status | -| --------------------------------------------------------------- | --------------------------------------- | --------------- | -| Developers browse and see MCP servers from MCP Registry | RHIDP-15166 (Browse page) | Closed | -| Developers browse and see models/model servers from RHOAI | RHIDP-15166 (Browse page) | Closed | -| Filter by category (`mcp-server`, `ai-model`), source connector | RHIDP-15166 + RHIDP-15449 (NFS filters) | Closed / Review | -| View detail page for RHOAI-sourced `ai-model` with version info | RHIDP-15167 (Entity page extensions) | New | -| View detail page for MCP Registry-sourced `mcp-server` | RHIDP-15167 (Entity page extensions) | New | -| RBAC visibility enforcement hides denied entities | RHIDP-15164 (consumes RHDHPLAN-1508) | In Progress | +| RHDHPLAN-1510 Goal (frontend aspect) | RHDHPLAN-1509 Coverage | Status | +| --------------------------------------------------------------- | --------------------------------------- | ---------------------- | +| Developers browse and see MCP servers from MCP Registry | RHIDP-15166 (Browse page) | Closed | +| ~~Developers browse and see models/model servers from RHOAI~~ | ~~RHIDP-15166 (Browse page)~~ | _(RHDHPLAN-404 scope)_ | +| Filter by category (`mcp-server`, `ai-model`), source connector | RHIDP-15166 + RHIDP-15449 (NFS filters) | Closed / Review | +| View detail page for RHOAI-sourced `ai-model` with version info | RHIDP-15167 (Entity page extensions) | New | +| View detail page for MCP Registry-sourced `mcp-server` | RHIDP-15167 (Entity page extensions) | New | +| RBAC visibility enforcement hides denied entities | RHIDP-15164 (consumes RHDHPLAN-1508) | In Progress | **Connector admin configuration UI** (enable/disable connectors, change endpoints, sync schedules) is covered by **RHDHPLAN-1513** (connector-config-hot-reload), not RHDHPLAN-1509 or RHDHPLAN-1510. @@ -65,7 +65,7 @@ All user-facing display of entities produced by RHDHPLAN-1510 connectors is deli RHDHPLAN-1510 is purely backend connector/ingestion work. All three epics are backend-only: - **RHIDP-15313 (MCP Registry):** Mirror endpoint config, custom CA bundles, K8s Secret auth, AI Asset annotation enrichment — all backend entity-provider work -- **RHIDP-15314 (RHOAI):** Kubeflow Model Registry API ingestion, RHOAI MCP catalog API ingestion, version normalization, per-source toggle — all backend entity-provider work +- **RHIDP-15314 (RHOAI):** RHOAI MCP catalog API ingestion, version normalization, enable/disable toggle — all backend entity-provider work _(Model Registry / Kubeflow is RHDHPLAN-404 scope)_ - **RHIDP-15316 (Cross-Connector):** Shared CA bundle utility, K8s Secret credential validation, fault isolation, reference config docs — all backend infrastructure and documentation The feature's out-of-scope section reinforces this: _"Installing, deploying, invoking, or proxying MCP servers, AI models, model servers, or AI skills from RHDH — this Feature is discovery/metadata ingestion only."_ From 20bbd2f089a39a89dcd6e23de6d14d16695f6dce Mon Sep 17 00:00:00 2001 From: gabemontero Date: Mon, 27 Jul 2026 15:01:43 -0400 Subject: [PATCH 14/18] yarn prettier:fix Signed-off-by: gabemontero --- workspaces/boost/openspec/changes/rhoai-connector/proposal.md | 2 ++ workspaces/boost/openspec/changes/rhoai-connector/tasks.md | 1 + .../specs/fine-grained-permissions/spec.md | 1 - 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/workspaces/boost/openspec/changes/rhoai-connector/proposal.md b/workspaces/boost/openspec/changes/rhoai-connector/proposal.md index d05c7839b8..dcc37fa41a 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/proposal.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/proposal.md @@ -16,7 +16,9 @@ Boost must surface RHOAI's MCP catalog as first-class API entities in the RHDH c > - **Llamastack/OGX:** New RHDHPLAN-1510 scope — Boost adds Llamastack/OGX as additional model information source alongside RHOAI. Separate connector work. > **RHDHPLAN-1510 Consolidation (2026-07-08):** Epic RHIDP-15315 (OCI Skill Registry Connector) was closed — its scope has been absorbed by RHIDP-15294 (OCI Skill Registry) under RHDHPLAN-1507. RHDHPLAN-1510 continues with 3 surviving epics: RHIDP-15313 (MCP Registry connector), RHIDP-15314 (this RHOAI connector), and RHIDP-15316 (Cross-Connector Shared Infrastructure). All TLS, CA bundle, and credential utilities referenced here depend on RHIDP-15316 stories (RHIDP-15265, 15329) being implemented first. + ## What Boost Builds + ### MCP Catalog Source - EntityProvider connecting to RHOAI 3.4 MCP catalog API (developer preview) diff --git a/workspaces/boost/openspec/changes/rhoai-connector/tasks.md b/workspaces/boost/openspec/changes/rhoai-connector/tasks.md index 3fb05fe3aa..2518979fa1 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/tasks.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/tasks.md @@ -10,6 +10,7 @@ > - RHIDP-15322 (MCP catalog source) is blocked by RHDHPLAN-1507 SDK (RHIDP-15258) for annotation scheme ## 1. MCP Catalog Source — RHIDP-15322 + - [ ] 1.1 Define RHOAI MCP catalog API response types with Zod schemas (`McpServer`, `McpCapabilities`) - [ ] 1.2 Implement `McpCatalogApiClient` in `src/providers/mcpCatalog/client.ts` with typed fetch - [ ] 1.3 Implement `RhoaiMcpCatalogProvider` extending `EntityProvider` diff --git a/workspaces/boost/openspec/changes/security-safety-governance/specs/fine-grained-permissions/spec.md b/workspaces/boost/openspec/changes/security-safety-governance/specs/fine-grained-permissions/spec.md index 0015758705..a57942528a 100644 --- a/workspaces/boost/openspec/changes/security-safety-governance/specs/fine-grained-permissions/spec.md +++ b/workspaces/boost/openspec/changes/security-safety-governance/specs/fine-grained-permissions/spec.md @@ -36,7 +36,6 @@ RBAC policies MUST govern agent lifecycle transitions with ownership and separat - **CONDITIONAL** — attach conditions to `req.boostPermissionConditions` for the handler to apply as filters - **AND** deployers can configure visibility rules via RBAC policies (e.g., `IS_OWNER` to show only the user's own agents, `HAS_LIFECYCLE_STAGE` to show only published agents) - #### Scenario: Self-approval prevention via IS_NOT_CREATOR rule - **WHEN** a user attempts to approve an agent (pending→published) From f2ca411db6588c4ce484597e4ea304935f3bd8a0 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Tue, 28 Jul 2026 10:17:49 -0400 Subject: [PATCH 15/18] fix rhdhplan-*-openspecs rebase hiccups (align with main branch) --- .../changes/connector-config-hot-reload/design.md | 5 ----- .../boost/openspec/changes/rhoai-connector/design.md | 10 ---------- .../boost/openspec/changes/rhoai-connector/proposal.md | 3 --- 3 files changed, 18 deletions(-) diff --git a/workspaces/boost/openspec/changes/connector-config-hot-reload/design.md b/workspaces/boost/openspec/changes/connector-config-hot-reload/design.md index a686db6ddd..7f362484c8 100644 --- a/workspaces/boost/openspec/changes/connector-config-hot-reload/design.md +++ b/workspaces/boost/openspec/changes/connector-config-hot-reload/design.md @@ -82,11 +82,6 @@ Each `boost.connectors..*` field is `configScope: db-overridable` — these | `schedule.cron` | `db-overridable` | Admin can change cron schedule at runtime | | `batchSize` | `db-overridable` | Admin can tune performance at runtime | | `timeout.connectionMs` | `db-overridable` | Admin can adjust for network conditions at runtime | -| `lastSyncTimestamp` | `db-only` | Runtime state written by provider after sync — no YAML baseline exists | -| `lastSyncOutcome` | `db-only` | Runtime state (success/failure) — written by provider, not configurable | -| `runStatus` | `db-only` | Transient state (running/idle) — no deployment-time equivalent | - -**Why db-only exists:** Some fields are pure runtime state — they are written by the system during operation and have no YAML baseline or admin-configurable equivalent. They live exclusively in the database and are never merged with YAML config. The `RuntimeConfigResolver` returns them as-is from the DB layer without two-layer merging. **Runtime state lives in the health store, not the config resolver:** Fields like `lastSyncTimestamp` and `lastSyncOutcome` are pure runtime state owned by the `boost_sync_attempts` table (see ingestion-health-dashboard Decision 1). They are not config — they are operational state written by providers after each sync. Run status (running/idle) is derived from these fields, not stored as a separate column. Querying them goes through the health API (`GET /api/boost/ingestion-health`), not `RuntimeConfigResolver`. diff --git a/workspaces/boost/openspec/changes/rhoai-connector/design.md b/workspaces/boost/openspec/changes/rhoai-connector/design.md index 330bd8bf58..75d8bb649c 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/design.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/design.md @@ -15,15 +15,6 @@ The MCP catalog API is developer preview in RHOAI 3.4; not all customers have up > - **MCP resource mapping deferred:** Mapping MCP resources (tools, prompts) as catalog entities is deferred for RHDH 2.1 (Christophe's consent; upstream due diligence pending). This connector emits MCP server entities only; MCP resource discovery is out of scope for now. > - **Llamastack/OGX:** New RHDHPLAN-1510 scope — Boost adds Llamastack/OGX as additional model information source alongside RHOAI. Separate connector work. -> **RHDHPLAN-1510 Consolidation (2026-07-08):** Epic RHIDP-15315 (OCI Skill Registry Connector) was closed — scope absorbed by RHIDP-15294 (RHDHPLAN-1507). This RHOAI connector continues under RHIDP-15314. Dependency chain: RHIDP-15316 cross-connector stories (15265 endpoint/creds, 15329 CA bundles) must land before this connector's deployment configuration (RHIDP-15323) can proceed. -> -> **Stakeholder Alignment (2026-07-13):** -> -> - **RHDHPLAN-393 complementary:** The RHOAI MCP catalog source and the MCP Registry connector (RHIDP-15313) serve different MCP server discovery paths — no ingestion duplication. RHDHPLAN-393 provides upstream MCP Registry; RHIDP-15313 adds productization. This connector ingests RHOAI-managed MCP servers separately. -> - **RHDHPLAN-404 dependency:** Provides extended API entity schema that this connector leverages for MCP server entities (`kind: API, spec.type: mcp-server`). Model Registry integration (Kubeflow API) is handled under RHDHPLAN-404, not this connector. -> - **MCP resource mapping deferred:** Mapping MCP resources (tools, prompts) as catalog entities is deferred for RHDH 2.1 (Christophe's consent; upstream due diligence pending). This connector emits MCP server entities only; MCP resource discovery is out of scope for now. -> - **Llamastack/OGX:** New RHDHPLAN-1510 scope — Boost adds Llamastack/OGX as additional model information source alongside RHOAI. Separate connector work. - ## Goals - MCP catalog API client with graceful degradation on 404/absence @@ -114,4 +105,3 @@ The provider uses the shared CA bundle utility from RHIDP-15316. K8s Secret cred - Shared annotation schema defined in RHDHPLAN-1507's `ai-catalog-entity-model` - SDK validation enforces annotation schema compliance - Automated tests verify annotation presence and correctness -- Automated tests verify annotation presence and correctness diff --git a/workspaces/boost/openspec/changes/rhoai-connector/proposal.md b/workspaces/boost/openspec/changes/rhoai-connector/proposal.md index dcc37fa41a..7630050716 100644 --- a/workspaces/boost/openspec/changes/rhoai-connector/proposal.md +++ b/workspaces/boost/openspec/changes/rhoai-connector/proposal.md @@ -15,8 +15,6 @@ Boost must surface RHOAI's MCP catalog as first-class API entities in the RHDH c > - **MCP resource mapping deferred:** Mapping MCP resources (tools, prompts) as catalog entities is deferred for RHDH 2.1 (Christophe's consent; upstream due diligence pending). This connector emits MCP server entities only; MCP resource discovery is out of scope for now. > - **Llamastack/OGX:** New RHDHPLAN-1510 scope — Boost adds Llamastack/OGX as additional model information source alongside RHOAI. Separate connector work. -> **RHDHPLAN-1510 Consolidation (2026-07-08):** Epic RHIDP-15315 (OCI Skill Registry Connector) was closed — its scope has been absorbed by RHIDP-15294 (OCI Skill Registry) under RHDHPLAN-1507. RHDHPLAN-1510 continues with 3 surviving epics: RHIDP-15313 (MCP Registry connector), RHIDP-15314 (this RHOAI connector), and RHIDP-15316 (Cross-Connector Shared Infrastructure). All TLS, CA bundle, and credential utilities referenced here depend on RHIDP-15316 stories (RHIDP-15265, 15329) being implemented first. - ## What Boost Builds ### MCP Catalog Source @@ -43,4 +41,3 @@ Boost must surface RHOAI's MCP catalog as first-class API entities in the RHDH c - `workspaces/boost/openspec/changes/ai-catalog-entity-model/` — annotation scheme and SDK validation (RHDHPLAN-1507) - `workspaces/boost/openspec/changes/connector-shared-infrastructure/` — shared CA bundle utility (RHIDP-15316) - RHDHPLAN-404 — Model Registry integration (Kubeflow API) handled separately -- RHDHPLAN-404 — Model Registry integration (Kubeflow API) handled separately From 2655e9e75e441f2a80784338ab70046cb9cb3ee6 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Tue, 28 Jul 2026 12:13:06 -0400 Subject: [PATCH 16/18] fix(boost): RHDHPLAN-1505 align JIRA-analysis docs with final openspec content - staged-issues: fix package name, function signatures (caller-passes-subtree), table name (boost_sync_attempts), config scope descriptions, add missing subtasks (createSafeRefresh, removeOverride, connector integration group) - feasibility-report: fix loadCaBundle signature to caller-passes-subtree pattern Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../RHDHPLAN-1510-feasibility-report.md | 2 +- .../rhdhplan1505-1-staged-issues.md | 101 ++++++++++-------- 2 files changed, 57 insertions(+), 46 deletions(-) diff --git a/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-feasibility-report.md b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-feasibility-report.md index 057045be75..e54fc86aa4 100644 --- a/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-feasibility-report.md +++ b/workspaces/boost/specifications/JIRA-analysis/RHDHPLAN-1510-feasibility-report.md @@ -133,7 +133,7 @@ RHDHPLAN-1510 is about connector implementations — entity providers that inges **Key design decisions:** -1. **CA bundle utility** — A shared function like `loadCaBundle(config: Config, connectorId: string): Buffer | undefined` that reads `catalog.providers..tls.caFile` or `catalog.providers..tls.caSecret` and returns the CA certificate for use in `https.Agent`. +1. **CA bundle utility** — A shared function like `loadCaBundle(connectorConfig: Config): Buffer | undefined` — caller passes the connector's Config subtree (e.g., `config.getConfig('catalog.providers.mcpRegistry')`), and the function reads `tls.caFile` or `tls.caSecret` within that subtree, returning the CA certificate for use in `https.Agent`. 2. **Fault isolation** — Backstage's per-provider entity buckets already provide data isolation. The shared infrastructure adds process-level isolation: `try/catch` + structured error logging in the scheduled task runner wrapper, ensuring one connector's unhandled error doesn't crash the Node.js process. diff --git a/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md index d7faec164a..4206b3f09b 100644 --- a/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md +++ b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md @@ -25,16 +25,16 @@ Each issue is scoped for a single fullsend `/fs-code` run. Frontend admin UI iss For now, we will be employing the RHDH process convention used for our Jira tracking for upstream work, where we'll remove RHDIP stories from sprints as needed, and put into Waiting, if there are sprint wide gaps for implementing various stages of a story. But as we progress, if further break up of a story is more seamless, we'll pursue that. But in other words, we will be honoring the Story granularity conventions in the RHDH skills used to craft our stories. -| RHIDP Story | Started (definition/foundation) | Completed (adoption/extension) | Referenced after completion | -| --------------------------------------------- | -------------------------------------------------- | ---------------------------------------------------- | --------------------------------------------- | -| RHIDP-15255 (Annotation Scheme) | Issue 2 — define annotations + validator | Issue 8 — update providers to emit annotations | — | -| RHIDP-15260 (SDK Package) | Issue 2 — create package + interfaces | Issue 8 — delta sync framework + publish | — | -| RHIDP-15273 (Graduated Visibility) | Issue 23 — SkillBundle filtered-skill UX | Issue 24 — RequirePermission gating on entity detail | — | -| RHIDP-15280 (Audit Logging) | Issue 21 — define + emit audit events | Issue 29 — analytics REST API consuming audit data | — | -| RHIDP-15306 (Admin Permission + Default-Deny) | Issue 3 — define `ai-catalog.admin` permission | Issue 20 — implement default-deny config | — | -| RHIDP-15316 (Shared Infra) | Issue 1 — build `@boost/connector-utils` | Issue 1 | Issues 13, 16 (integrate CA bundle utility) | -| RHIDP-15335 (Health API) | Issue 5 — health API + data model | Issue 26 — force sync routes using health data | — | -| RHIDP-15259 (SDK Interface) | Issue 2 — define `AIAssetEntityProvider` interface | Issue 2 | Issue 8 (providers compile against interface) | +| RHIDP Story | Started (definition/foundation) | Completed (adoption/extension) | Referenced after completion | +| --------------------------------------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------- | --------------------------------------------- | +| RHIDP-15255 (Annotation Scheme) | Issue 2 — define annotations + validator | Issue 8 — update providers to emit annotations | — | +| RHIDP-15260 (SDK Package) | Issue 2 — create package + interfaces | Issue 8 — delta sync framework + publish | — | +| RHIDP-15273 (Graduated Visibility) | Issue 23 — SkillBundle filtered-skill UX | Issue 24 — RequirePermission gating on entity detail | — | +| RHIDP-15280 (Audit Logging) | Issue 21 — define + emit audit events | Issue 29 — analytics REST API consuming audit data | — | +| RHIDP-15306 (Admin Permission + Default-Deny) | Issue 3 — define `ai-catalog.admin` permission | Issue 20 — implement default-deny config | — | +| RHIDP-15316 (Shared Infra) | Issue 1 — build `@red-hat-developer-hub/backstage-plugin-boost-connector-utils` | Issue 1 | Issues 13, 16 (integrate CA bundle utility) | +| RHIDP-15335 (Health API) | Issue 5 — health API + data model | Issue 26 — force sync routes using health data | — | +| RHIDP-15259 (SDK Interface) | Issue 2 — define `AIAssetEntityProvider` interface | Issue 2 | Issue 8 (providers compile against interface) | --- @@ -51,19 +51,19 @@ _GitHub issue not yet created_ **RHIDP Stories:** RHIDP-15265, RHIDP-15266, RHIDP-15329, RHIDP-15330 **Feature:** RHDHPLAN-1510 — Epic RHIDP-15316 -Create the `@boost/connector-utils` shared package providing CA bundle resolution, fault isolation wrappers, enable/disable patterns, and configurable endpoint/credential validation. All entity-provider connectors (MCP Registry, RHOAI, OCI Skill) depend on this package. Includes reference app-config YAML for air-gapped deployment with Helm and Operator CR examples. +Create the `@red-hat-developer-hub/backstage-plugin-boost-connector-utils` shared package providing CA bundle resolution, fault isolation wrappers (including `createSafeRefresh()` for scheduled refresh callbacks), enable/disable patterns, and configurable endpoint/credential validation. All entity-provider connectors (MCP Registry, RHOAI, OCI Skill) depend on this package. Includes reference app-config YAML for air-gapped deployment with Helm and Operator CR examples, plus connector integration tasks to wire each connector to the shared package. ### Tasks From `openspec/changes/connector-shared-infrastructure/tasks.md` group 1 (RHIDP-15329): -- 1.1 Create `@boost/connector-utils` package with `package.json`, TypeScript config, and README -- 1.2 Define `loadCaBundle(config: Config, connectorId: string): Buffer | undefined` function signature -- 1.3 Implement caFile resolution — read CA from `catalog.providers..tls.caFile` mount path -- 1.4 Implement caSecret resolution — read CA from `catalog.providers..tls.caSecret.$env` environment variable -- 1.5 Add per-connector config isolation — `loadCaBundle()` reads only the specified connector's CA config +- 1.1 Create `@red-hat-developer-hub/backstage-plugin-boost-connector-utils` package with `package.json`, TypeScript config, and README +- 1.2 Define `loadCaBundle(connectorConfig: Config): Buffer | undefined` function signature — caller passes the Config subtree containing the `tls` block +- 1.3 Implement caFile resolution — read CA from `tls.caFile` within the provided Config subtree +- 1.4 Implement caSecret resolution — read CA from `tls.caSecret.$env` within the provided Config subtree +- 1.5 Add per-connector config isolation — each connector resolves its own Config nesting before calling `loadCaBundle()` (e.g., MCP passes `config.getConfig('catalog.providers.mcpRegistry')`, RHOAI passes `config.getConfig('catalog.providers.rhoai.mcpCatalog')`, OCI passes per-registry Config node) - 1.6 Create `https.Agent` factory utility: `createHttpsAgent(caBundle?: Buffer): https.Agent | undefined` -- 1.7 Handle missing CA file: log INFO-level warning with expected file path, return `undefined` +- 1.7 Handle missing CA file: log WARN-level warning with expected file path, return `undefined` (don't crash) - 1.8 Handle invalid/expired CA certificate: log ERROR with certificate details - 1.9 Support CA certificate chains (concatenated PEM blocks) - 1.10–1.15 Unit tests for CA bundle utility (file path, env var, missing, invalid, chain, isolation) @@ -71,18 +71,19 @@ From `openspec/changes/connector-shared-infrastructure/tasks.md` group 1 (RHIDP- From `openspec/changes/connector-shared-infrastructure/tasks.md` group 2 (RHIDP-15330): - 2.1 Define `ConnectorErrorContext` interface -- 2.2 Create `createProviderWrapper(provider, logger): EntityProvider` function -- 2.3 Implement try/catch wrapper around `provider.run()` to catch unhandled rejections -- 2.4 Implement structured error logging with connector context fields -- 2.5 Log errors via Backstage `LoggerService` for structured JSON output -- 2.6 Ensure wrapper does NOT rethrow errors — allow catalog backend to continue -- 2.7 Verify Backstage entity bucket isolation per provider -- 2.8–2.10 Unit tests for fault isolation wrapper +- 2.2 Create `createProviderWrapper(provider: EntityProvider, logger: LoggerService): EntityProvider` function +- 2.3 Implement try/catch wrapper around provider `connect()` via `createProviderWrapper()` to catch unhandled rejections +- 2.4 Implement `createSafeRefresh()` — try/catch wrapper around scheduled refresh callback to catch unhandled rejections +- 2.5 Implement structured error logging with connector context fields +- 2.6 Log errors via Backstage `LoggerService` for structured JSON output +- 2.7 Ensure wrappers do NOT rethrow errors — allow catalog backend to continue +- 2.8 Verify Backstage entity bucket isolation per provider (documentation + integration test) +- 2.9–2.11 Unit tests for fault isolation wrapper From `openspec/changes/connector-shared-infrastructure/tasks.md` group 3 (RHIDP-15330): - 3.1 Define enable/disable config schema: `catalog.providers..enabled: boolean` -- 3.2 Create `isConnectorEnabled(config, connectorId): boolean` utility +- 3.2 Create `isConnectorEnabled(connectorConfig: Config): boolean` utility — caller passes the Config subtree (same pattern as `loadCaBundle`) - 3.3 Implement config reader: return `true` if `enabled` is omitted (default enabled) - 3.4 Create registration guard pattern for backend module `init()` example in README - 3.5 Log INFO-level message when connector is disabled @@ -91,7 +92,7 @@ From `openspec/changes/connector-shared-infrastructure/tasks.md` group 3 (RHIDP- From `openspec/changes/connector-shared-infrastructure/tasks.md` group 4: -- 4.1 Export shared utilities from `src/index.ts` +- 4.1 Export shared utilities from `src/index.ts`: `loadCaBundle`, `createHttpsAgent`, `createProviderWrapper`, `createSafeRefresh`, `isConnectorEnabled`, `ConnectorErrorContext` - 4.2–4.7 Documentation: app-config schema, enable/disable, error logging, examples for each connector - 4.8 Add JSDoc comments for all exported functions @@ -109,6 +110,15 @@ From `openspec/changes/connector-shared-infrastructure/tasks.md` group 6 (RHIDP- - 6.6 Add air-gapped deployment variant - 6.7 Place reference YAML in `workspaces/boost/examples/` +From `openspec/changes/connector-shared-infrastructure/tasks.md` group 7 (Connector Integration): + +- 7.1 Update MCP Registry connector to consume `@red-hat-developer-hub/backstage-plugin-boost-connector-utils` +- 7.2 Update RHOAI connector to consume `@red-hat-developer-hub/backstage-plugin-boost-connector-utils` +- 7.3 Update OCI Skill connector to consume `@red-hat-developer-hub/backstage-plugin-boost-connector-utils` +- 7.4 Verify all three connectors use consistent CA bundle loading pattern +- 7.5 Verify all three connectors use consistent enable/disable config +- 7.6 Verify all three connectors use consistent structured error logging + From `openspec/changes/ai-catalog-entity-model/tasks.md` group 6 (RHIDP-15265 — moved to RHIDP-15316): - 6.3 Implement startup validation rejecting plaintext credentials with descriptive error message @@ -298,14 +308,14 @@ _GitHub issue not yet created_ **RHIDP Stories:** RHIDP-15335, RHIDP-15337 **Feature:** RHDHPLAN-1513 — Epic RHIDP-15331 -Implement the ingestion health backend: `sync_attempts` table with database migration, `SyncAttemptsRepository`, `HealthStatusService` with status derivation (healthy/degraded/failing based on last 3 attempts), `GET /api/boost/ingestion-health` REST endpoint, and `ErrorClassifier` utility with actionable diagnostic guidance for auth failures, network errors, schema mismatches, and rate limits. The admin UI consuming this API is in Issue 26. +Implement the ingestion health backend: `boost_sync_attempts` table with database migration, `SyncAttemptsRepository`, `HealthStatusService` with status derivation (healthy/degraded/failing/unknown based on last 3 attempts; unknown = zero sync attempts recorded), `GET /api/boost/ingestion-health` REST endpoint with `ai-catalog.admin` RBAC gating, and `ErrorClassifier` utility with actionable diagnostic guidance for auth failures, network errors, schema mismatches, and rate limits. The admin UI consuming this API is in Issue 26. ### Tasks From `openspec/changes/ingestion-health-dashboard/tasks.md` group 1 (RHIDP-15335): -- 1.1 Define `sync_attempts` table schema in database migration -- 1.2 Create database migration file with indexes on (connector_id, timestamp DESC) +- 1.1 Define `boost_sync_attempts` table schema in database migration (connector_id, timestamp, outcome, error_type, error_message, assets_added/updated/removed, duration_ms) +- 1.2 Create database migration file for `boost_sync_attempts` table with indexes on (connector_id, timestamp DESC) - 1.3 Implement `SyncAttemptsRepository` class with methods: `insertSyncAttempt()`, `getLatestAttempts()`, `cleanupOldAttempts()` - 1.4 Add retention policy config schema (`boost.ingestion.healthRetention.maxAttemptsPerConnector`, default 100) - 1.5 Implement scheduled cleanup job for sync attempts (daily, enforces retention) @@ -315,10 +325,10 @@ From `openspec/changes/ingestion-health-dashboard/tasks.md` group 2 (RHIDP-15335 - 2.1 Define `ConnectorHealthStatus` type in `plugins/boost-common/src/types/ingestion-health.ts` - 2.2 Implement `GET /api/boost/ingestion-health` route returning array of connector health objects -- 2.3 Implement health status derivation logic in `HealthStatusService.deriveStatus(attempts)` +- 2.3 Implement health status derivation logic in `HealthStatusService.deriveStatus(attempts)` (healthy/degraded/failing/unknown based on last 3 attempts; unknown = zero sync attempts recorded) - 2.4 Add `?includeDisabled=true` query parameter support -- 2.5 Implement RBAC gating via boost admin permissions check -- 2.6 Add audit logging for health API requests +- 2.5 Implement RBAC gating via `ai-catalog.admin` permission check in route handler (using `permissions.authorize()`) +- 2.6 Add audit logging for health API requests (per RHDHPLAN-1508 RHIDP-15277 audit logging pattern) - 2.7 Implement empty state handling - 2.8 Add health API integration tests @@ -351,14 +361,14 @@ _GitHub issue not yet created_ **RHIDP Stories:** RHIDP-15340 **Feature:** RHDHPLAN-1513 — Epic RHIDP-15332 -Define Zod connector config schemas (Jira, GitHub, GitLab) with field-level `configScope` annotations (`db-overridable` vs `yaml-only`), and extend `RuntimeConfigResolver` to support connector config scope with two-layer merge (YAML baseline + DB overrides), 30s TTL cache with immediate invalidation, and schema validation during merge. Hot-reload propagation to connectors is in Issue 22; admin UI is in Issue 28. +Define Zod connector config schemas (Jira, GitHub, GitLab) covering `boost.connectors` fields only — all fields are `configScope: db-overridable` (deployment-time fields like `credentials.*`, `tls.*`, and `namespace` live under `ai-catalog.providers..*` and are excluded from this schema entirely). Extend `RuntimeConfigResolver` to support connector config scope with two-layer merge (YAML baseline + DB overrides), 30s TTL cache with immediate invalidation, and schema validation during merge. Hot-reload propagation to connectors is in Issue 22; admin UI is in Issue 28. ### Tasks From `openspec/changes/connector-config-hot-reload/tasks.md` group 1 (RHIDP-15340): -- 1.1 Define Jira connector config Zod schema with fields: `enabled`, `endpoint`, `schedule.*`, `credentials.*`, `namespace`, `batchSize`, `timeout.*` -- 1.2 Annotate each field with `configScope`: `enabled`, `endpoint`, `schedule.*`, `batchSize`, `timeout.*` → `db-overridable`; `credentials.*`, `namespace` → `yaml-only` +- 1.1 Define Jira connector config Zod schema with `boost.connectors` fields only: `enabled` (boolean), `endpoint` (URL), `schedule.intervalMs` (number), `schedule.cron` (string), `batchSize` (number), `timeout.connectionMs` (number). Note: `tls.caFile`, `credentials.*`, and `namespace` are `ai-catalog.providers` fields — not part of the `boost.connectors` schema. +- 1.2 All `boost.connectors` fields are `configScope: db-overridable` (deployment-time fields like `credentials.*`, `tls.*`, and `namespace` live under `ai-catalog.providers..*`) - 1.3 Define GitHub connector config Zod schema - 1.4 Define GitLab connector config Zod schema - 1.5 Add URL validation for `endpoint` field @@ -371,7 +381,7 @@ From `openspec/changes/connector-config-hot-reload/tasks.md` group 1 (RHIDP-1534 From `openspec/changes/connector-config-hot-reload/tasks.md` group 2 (RHIDP-15340): - 2.1 Extend `RuntimeConfigResolver` to support connector config scope -- 2.2 Implement `getConfig(key)` method for connector config keys +- 2.2 Extend `resolve(key: BoostConfigKey)` method to support connector leaf config keys (e.g., `boost.connectors.jira.enabled`) - 2.3 Implement two-layer merge: YAML baseline from `ConfigApi` + DB overrides from `AdminConfigService` - 2.4 Implement cache with 30s TTL for merged connector config - 2.5 Implement immediate cache invalidation on DB override write @@ -1034,16 +1044,16 @@ _GitHub issue not yet created_ **RHIDP Stories:** RHIDP-15341 **Feature:** RHDHPLAN-1513 — Epic RHIDP-15332 -Update Jira, GitHub, and GitLab entity providers to read config via `RuntimeConfigResolver.getConfig()` at each reconciliation cycle start, implementing enable/disable check, endpoint URL propagation, schedule change propagation (reschedule task), credential re-read from mounted Secret per cycle, and config change logging. +Update Jira, GitHub, and GitLab entity providers to read config via `RuntimeConfigResolver.resolve()` (leaf keys like `boost.connectors.jira.enabled`) at each reconciliation cycle start, implementing enable/disable check, endpoint URL propagation, schedule change propagation (reschedule task with new `schedule.intervalMs` or `schedule.cron`), credential re-read from mounted Secret per cycle, and config change logging. ### Tasks From `openspec/changes/connector-config-hot-reload/tasks.md` group 3 (RHIDP-15341): -- 3.1 Update Jira entity provider to read config via `RuntimeConfigResolver.getConfig('connectors.jira')` at reconciliation cycle start +- 3.1 Update Jira entity provider to read config via `RuntimeConfigResolver.resolve('boost.connectors.jira.enabled')` (and other leaf keys) at reconciliation cycle start - 3.2 Implement enable/disable check: skip sync if `enabled: false` - 3.3 Implement endpoint URL propagation -- 3.4 Implement schedule change propagation: reschedule task +- 3.4 Implement schedule change propagation: reschedule task with new `schedule.intervalMs` or `schedule.cron` from merged config - 3.5 Update GitHub entity provider with same hot-reload pattern - 3.6 Update GitLab entity provider with same hot-reload pattern - 3.7 Add config change logging: log old → new values @@ -1269,12 +1279,13 @@ From `openspec/changes/connector-config-hot-reload/tasks.md` group 4 (RHIDP-1534 From `openspec/changes/connector-config-hot-reload/tasks.md` group 6: -- 6.1 Add connector config endpoints to `AdminConfigService` backend API -- 6.2 Implement Zod schema validation in `setConfig()` before DB write -- 6.3 Implement `configScope` enforcement -- 6.4 Implement cache invalidation call -- 6.5 Add audit logging for connector config changes -- 6.6 Add unit tests for `AdminConfigService` connector config methods +- 6.1 Extend existing `POST /api/boost/admin/config` endpoint to accept connector config keys (e.g., `{ key: "boost.connectors.jira.enabled", value: false }`). Add `GET /api/boost/admin/config?key=boost.connectors.` for reading merged connector config. +- 6.2 Implement Zod schema validation in `setOverride()` method before DB write +- 6.3 Implement `configScope` enforcement: reject writes for `yaml-only` fields +- 6.4 Implement cache invalidation call to `RuntimeConfigResolver.invalidate()` after DB write +- 6.5 Implement `removeOverride(key: BoostConfigKey)` method and `DELETE /api/boost/admin/config?key=` endpoint — deletes the DB override row, calls `RuntimeConfigResolver.invalidate()`, and returns the reverted YAML baseline value. Used when switching schedule types (e.g., removing `intervalMs` override when switching to `cron`). +- 6.6 Add audit logging for connector config changes (timestamp, user, changed fields, old/new values) +- 6.7 Add unit tests for `AdminConfigService` connector config methods (including `removeOverride`) ### Specifications From 9987bf01a2dac96036323f032e9ccfee8105f414 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Tue, 28 Jul 2026 15:49:32 -0400 Subject: [PATCH 17/18] fix(boost): RHDHPLAN-1505 cite RHDHPLAN-393 RHIDP-15655 dependency in staged issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issues 7, 13, 14 (RHIDP-15317/15318/15319 — MCP Registry Connector productization) depend on RHDHPLAN-393's RHIDP-15655 (upstream MCP Registry entity provider). Added cross-feature dependency notes to header and each affected issue. Issue 14 additionally depends on RHIDP-15658 (entity mapping). RHIDP-15321 (RHOAI version normalization) and Issues 15-16 (RHOAI connector) have no RHDHPLAN-393 dependency — they query RHOAI's own MCP catalog API independently. Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../JIRA-analysis/rhdhplan1505-1-staged-issues.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md index 4206b3f09b..9a6ed4cb86 100644 --- a/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md +++ b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md @@ -13,10 +13,11 @@ Each issue is scoped for a single fullsend `/fs-code` run. Frontend admin UI iss | RHDHPLAN-1510 | RHIDP-15313 (MCP Registry), RHIDP-15314 (RHOAI Connector), RHIDP-15316 (Cross-Connector Shared Infra) | | RHDHPLAN-1513 | RHIDP-15331 (Health Dashboard), RHIDP-15332 (Hot-Reload), RHIDP-15334 (Schema Alignment) | -**Cross-feature dependencies (RHDHPLAN-1509):** +**Cross-feature dependencies (RHDHPLAN-1509, RHDHPLAN-393):** - Issue 24 (RHIDP-15273 Graduated Visibility Frontend) depends on RHIDP-15167 (Entity page extensions, RHDHPLAN-1509) - RHIDP-15167 (RHDHPLAN-1509) depends on RHIDP-15335 (Issue 5 — Health API), creating a cross-feature cycle that must be resolved by building the API (Issue 5) first +- Issues 7, 13, 14 (RHIDP-15317, RHIDP-15318, RHIDP-15319 — MCP Registry Connector productization under RHDHPLAN-1510) depend on RHIDP-15655 (Implement MCP Registry entity provider, RHDHPLAN-393). The upstream community entity provider must exist before the productization wrapper can configure its endpoint (Issue 7), integrate TLS/credentials (Issue 13), or intercept entity emission for annotation enrichment (Issue 14). RHIDP-15321 (RHOAI version normalization, also in Issue 7) and Issues 15–16 (RHOAI connector) have no RHDHPLAN-393 dependency — they query RHOAI's own MCP catalog API independently. **Maximum parallelism:** All 7 Tier 0 issues can start simultaneously. Within Tier 1, issues [17–19] (Neo4j) are independent of [9–12] (OCI) and [13–16] (MCP/RHOAI). Within Tier 2, issues [23–25] (RBAC UI) are independent of [26–29] (Ingestion UI). @@ -405,8 +406,9 @@ _GitHub issue not yet created_ **Dependencies:** None **RHIDP Stories:** RHIDP-15317, RHIDP-15321 **Feature:** RHDHPLAN-1510 — Epics RHIDP-15313, RHIDP-15314 +**Cross-feature dependency:** RHIDP-15317 depends on RHIDP-15655 (Implement MCP Registry entity provider, RHDHPLAN-393). The upstream community provider must exist before the productization layer can override its endpoint configuration. RHIDP-15321 (RHOAI version normalization) has no RHDHPLAN-393 dependency and can start immediately. -Implement the MCP Registry mirror endpoint configuration with zero-internet validation (no outbound traffic to public endpoint when mirror is configured), startup health check, and non-HTTPS security warnings. Also implement RHOAI version normalization utility for MCP server entity `rhdh.io/ai-asset-version` annotation population. These two stories have no cross-connector dependencies and can start immediately. +Implement the MCP Registry mirror endpoint configuration with zero-internet validation (no outbound traffic to public endpoint when mirror is configured), startup health check, and non-HTTPS security warnings. Also implement RHOAI version normalization utility for MCP server entity `rhdh.io/ai-asset-version` annotation population. RHIDP-15321 has no cross-connector dependencies and can start immediately; RHIDP-15317 is blocked on the upstream MCP Registry entity provider (RHDHPLAN-393 RHIDP-15655). ### Tasks @@ -671,6 +673,7 @@ _GitHub issue not yet created_ **Depends on:** Issue 1 (shared infra), Issue 7 (mirror endpoint) **RHIDP Stories:** RHIDP-15318 **Feature:** RHDHPLAN-1510 — Epic RHIDP-15313 +**Cross-feature dependency:** RHIDP-15318 depends on RHIDP-15655 (Implement MCP Registry entity provider, RHDHPLAN-393). The upstream community provider must exist as the integration target for TLS/credential wrapping. Integrate shared CA bundle utility (`loadCaBundle()`) from `@boost/connector-utils`, implement K8s Secret-based authentication (Basic Auth and Bearer token), Secret data caching with 5-minute TTL and invalidation on 401, and per-connector TLS configuration isolation. @@ -712,6 +715,7 @@ _GitHub issue not yet created_ **Depends on:** Issue 8 (SDK validation layer), Issue 13 (TLS hardening) **RHIDP Stories:** RHIDP-15319 **Feature:** RHDHPLAN-1510 — Epic RHIDP-15313 +**Cross-feature dependency:** RHIDP-15319 depends on RHIDP-15655 (Implement MCP Registry entity provider, RHDHPLAN-393) and RHIDP-15658 (Implement MCP Registry to entity mapping, RHDHPLAN-393). The upstream provider and its entity mapping must exist before the productization wrapper can intercept entity emission for annotation enrichment. Implement `RhdhMcpRegistryProviderWrapper` class intercepting entity emission to enrich with AI Asset annotations (`rhdh.io/ai-asset-category: "mcp-server"`, `rhdh.io/ai-asset-source: "mcp-registry"`, extracted version), integrate with SDK validation layer, and preserve existing annotations. From 81e2da57602c7ceaf1ea671ec6256e18e26fc431 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Tue, 28 Jul 2026 16:21:24 -0400 Subject: [PATCH 18/18] =?UTF-8?q?docs(boost):=20RHDHPLAN-1505=20correlate?= =?UTF-8?q?=2029=20staged=20issues=20with=20GitHub=20#4039=E2=80=93#4067?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- .../rhdhplan1505-1-staged-issues.md | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md index 9a6ed4cb86..42f48bf7e8 100644 --- a/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md +++ b/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md @@ -45,7 +45,7 @@ But as we progress, if further break up of a story is more seamless, we'll pursu ## Cross-Connector Shared Infrastructure Package (issue 1 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4039 **Labels:** `ready-to-code` **Dependencies:** None @@ -137,7 +137,7 @@ From `openspec/changes/ai-catalog-entity-model/tasks.md` group 6 (RHIDP-15265 ## Entity-Provider SDK — Types, Interfaces, Annotation Validation (issue 2 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4040 **Labels:** `ready-to-code` **Dependencies:** None @@ -189,7 +189,7 @@ From `openspec/changes/ai-catalog-entity-model/tasks.md` group 4 (RHIDP-15303): ## AI Catalog Permissions, Backend Enforcement, Conditional Rules (issue 3 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4041 **Labels:** `ready-to-code` **Dependencies:** None @@ -236,7 +236,7 @@ From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 4 (RHIDP-1531 ## Upstream Schema Alignment — Annotation Spec, Migration Design & Tooling (issue 4 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4042 **Labels:** `ready-to-code` **Dependencies:** None @@ -302,7 +302,7 @@ From `openspec/changes/ai-catalog-entity-model/tasks.md` group 8 (RHIDP-15302): ## Ingestion Health — API, Data Model, Error Classification (issue 5 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4043 **Labels:** `ready-to-code` **Dependencies:** None @@ -355,7 +355,7 @@ From `openspec/changes/ingestion-health-dashboard/tasks.md` group 3 (RHIDP-15337 ## Connector Config — Zod Schemas and RuntimeConfigResolver Extension (issue 6 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4044 **Labels:** `ready-to-code` **Dependencies:** None @@ -400,7 +400,7 @@ From `openspec/changes/connector-config-hot-reload/tasks.md` group 2 (RHIDP-1534 ## MCP Mirror Endpoint + RHOAI Version Normalization (issue 7 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4045 **Labels:** `ready-to-code` **Dependencies:** None @@ -451,7 +451,7 @@ From `openspec/changes/rhoai-connector/tasks.md` group 7 (RHIDP-15321): ## SDK — Delta Sync Framework and Package Publish (issue 8 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4046 **Labels:** `ready-to-code` **Depends on:** Issue 1 (shared infra exports), Issue 2 (types/interfaces) @@ -495,7 +495,7 @@ From `openspec/changes/ai-catalog-entity-model/tasks.md` group 9 (RHIDP-15260): ## OCI Skill Registry — Core Connector (issue 9 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4047 **Labels:** `ready-to-code` **Depends on:** Issue 1 (shared infra), Issue 8 (SDK) @@ -552,7 +552,7 @@ From `openspec/changes/oci-skill-connector/tasks.md` group 2 (RHIDP-15325): ## OCI — Multi-Registry and Air-Gapped Support (issue 10 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4048 **Labels:** `ready-to-code` **Depends on:** Issue 1 (shared infra), Issue 9 (core connector) @@ -584,7 +584,7 @@ From `openspec/changes/oci-skill-connector/tasks.md` group 4 (RHIDP-15327): ## OCI — Digest-Based Incremental Sync (issue 11 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4049 **Labels:** `ready-to-code` **Depends on:** Issue 1 (shared infra), Issue 9 (core connector) @@ -625,7 +625,7 @@ From `openspec/changes/oci-skill-connector/tasks.md` group 3 (RHIDP-15326): ## OCI — Load Testing and Scale Validation (issue 12 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4050 **Labels:** `ready-to-code` **Depends on:** Issue 1 (shared infra), Issue 9 (core connector) @@ -667,7 +667,7 @@ From `openspec/changes/oci-skill-connector/tasks.md` group 5 (RHIDP-15328): ## MCP Registry — TLS and Credential Hardening (issue 13 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4051 **Labels:** `ready-to-code` **Depends on:** Issue 1 (shared infra), Issue 7 (mirror endpoint) @@ -709,7 +709,7 @@ From `openspec/changes/mcp-registry-connector/tasks.md` group 2 (RHIDP-15318): ## MCP Registry — AI Asset Annotation Enrichment (issue 14 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4052 **Labels:** `ready-to-code` **Depends on:** Issue 8 (SDK validation layer), Issue 13 (TLS hardening) @@ -746,7 +746,7 @@ From `openspec/changes/mcp-registry-connector/tasks.md` group 3 (RHIDP-15319): ## RHOAI — MCP Catalog Source and Module Scaffold (issue 15 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4053 **Labels:** `ready-to-code` **Depends on:** Issue 8 (SDK annotation scheme) @@ -790,7 +790,7 @@ From `openspec/changes/rhoai-connector/tasks.md` group 3: ## RHOAI — Deployment Config and Cross-Cluster Endpoint (issue 16 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4054 **Labels:** `ready-to-code` **Depends on:** Issue 1 (shared infra CA/credential utils), Issue 15 (MCP catalog provider) @@ -821,7 +821,7 @@ From `openspec/changes/rhoai-connector/tasks.md` group 2 (RHIDP-15323): ## Neo4j Knowledge Graph — Core Sync Adapter (issue 17 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4055 **Labels:** `ready-to-code` **Depends on:** Issue 2 (SDK interfaces — `Neo4jSyncAdapter`) @@ -881,7 +881,7 @@ From `openspec/changes/neo4j-knowledge-graph/tasks.md` group 5 (RHIDP-15299): ## Neo4j — SkillBundle Support (issue 18 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4056 **Labels:** `ready-to-code` **Depends on:** Issue 17 (core sync adapter) @@ -909,7 +909,7 @@ From `openspec/changes/neo4j-knowledge-graph/tasks.md` group 4 (RHIDP-15300): ## Neo4j — Setup Documentation and Observability (issue 19 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4057 **Labels:** `ready-to-code` **Depends on:** Issue 17 (core sync adapter), Issue 18 (SkillBundle support) @@ -952,7 +952,7 @@ From `openspec/changes/neo4j-knowledge-graph/tasks.md` groups 8–9: ## Version-Level Policy Cascade and Default-Deny Configuration (issue 20 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4058 **Labels:** `ready-to-code` **Depends on:** Issue 3 (permission definitions) @@ -994,7 +994,7 @@ From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 6 (RHIDP-1530 ## RBAC Audit Logging (issue 21 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4059 **Labels:** `ready-to-code` **Depends on:** Issue 3 (permission definitions) @@ -1041,7 +1041,7 @@ Group 4 (Disconnected Cluster Support): ## Hot-Reload Propagation to Active Connectors (issue 22 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4060 **Labels:** `ready-to-code` **Depends on:** Issue 6 (Zod schemas, RuntimeConfigResolver) @@ -1083,7 +1083,7 @@ From `openspec/changes/connector-config-hot-reload/tasks.md` group 5 (RHIDP-1534 ## SkillBundle RBAC Filtering (issue 23 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4061 **Labels:** `ready-to-code` **Depends on:** Issue 3 (permission definitions) @@ -1112,7 +1112,7 @@ From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 9 (RHIDP-1531 ## Graduated Visibility — Frontend (issue 24 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4062 **Labels:** `ready-to-code` **Depends on:** Issue 3 (permission definitions) @@ -1139,7 +1139,7 @@ From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 3 (RHIDP-1527 ## RBAC Admin UI — Dashboard, Policy Editor, Default Posture (issue 25 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4063 **Labels:** `ready-to-code` **Depends on:** Issue 3 (permission definitions), Issue 20 (policy cascade + default-deny backend) @@ -1169,7 +1169,7 @@ From `openspec/changes/ai-catalog-asset-governance/tasks.md` group 8 (RHIDP-1530 ## Ingestion Health Admin UI and Disconnected-Cluster View (issue 26 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4064 **Labels:** `ready-to-code` **Depends on:** Issue 5 (health API, error classification) @@ -1224,7 +1224,7 @@ From `openspec/changes/ingestion-health-dashboard/tasks.md` group 8: ## Neo4j Graph Sync Status Panel (issue 27 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4065 **Labels:** `ready-to-code` **Depends on:** Issue 5 (health API), Issue 17 (Neo4j core sync adapter) @@ -1255,7 +1255,7 @@ From `openspec/changes/ingestion-health-dashboard/tasks.md` group 5 (RHIDP-15338 ## Connector Config Admin UI (issue 28 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4066 **Labels:** `ready-to-code` **Depends on:** Issue 6 (Zod schemas), Issue 22 (hot-reload propagation) @@ -1299,7 +1299,7 @@ From `openspec/changes/connector-config-hot-reload/tasks.md` group 6: ## Ingestion Analytics API and Eval Hub Integration (issue 29 of 29) -_GitHub issue not yet created_ +https://github.com/redhat-developer/rhdh-plugins/issues/4067 **Labels:** `ready-to-code` **Depends on:** Issue 5 (health data model), Issue 21 (audit logging)