Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b30a2cb
fix(boost): RHDHPLAN-1508 upgrade boost.agent.list to resource-based …
gabemontero Jul 13, 2026
0ca666b
chore(boost): RHDHPLAN-1510 openspec content for connector implementa…
gabemontero Jul 8, 2026
d7670d8
fix(boost): RHDHPLAN-1510 openspec consolidation annotations for epic…
gabemontero Jul 8, 2026
66f29fb
fix(boost): RHDHPLAN-1510 remove Model Registry scope from RHOAI conn…
gabemontero Jul 13, 2026
5b7862d
fix(boost): RHDHPLAN-1510 post-rebase openspec consistency fixes
gabemontero Jul 14, 2026
586b644
fix(boost): RHDHPLAN-1513 document db-only configScope for runtime-on…
gabemontero Jul 16, 2026
b298d1c
docs(boost): RHDHPLAN-1505 frontend coverage analysis for 1507/1508/1…
gabemontero Jul 17, 2026
4bff1b3
fix(boost): RHDHPLAN-1505 clarify 1509 dependency hub and admin-facin…
gabemontero Jul 17, 2026
6ec34b6
docs(boost): RHDHPLAN-1505 staged GitHub issues for 1507/1508/1510/1513
gabemontero Jul 17, 2026
906c211
docs(boost): RHDHPLAN-1513 deferral impact analysis on 2.1 staging
gabemontero Jul 20, 2026
75aa5c6
fix(boost): RHDHPLAN-1505 align staging plan with openspec review cha…
gabemontero Jul 21, 2026
5c686a6
fix(boost): RHDHPLAN-1505 align staging plan with RHDHPLAN-1508 post-…
gabemontero Jul 24, 2026
8e56f16
fix(boost): RHDHPLAN-1510 remove stale Model Registry/Kubeflow refere…
gabemontero Jul 27, 2026
cd5fd83
yarn prettier:fix
gabemontero Jul 27, 2026
4e901e8
fix rhdhplan-*-openspecs rebase hiccups (align with main branch)
gabemontero Jul 28, 2026
de696c8
fix(boost): RHDHPLAN-1505 align JIRA-analysis docs with final openspe…
gabemontero Jul 28, 2026
e570b21
fix(boost): RHDHPLAN-1505 cite RHDHPLAN-393 RHIDP-15655 dependency in…
gabemontero Jul 28, 2026
663732b
docs(boost): RHDHPLAN-1505 correlate 29 staged issues with GitHub #40…
gabemontero Jul 28, 2026
79ec4be
fix(boost): RHDHPLAN-1505 address fullsend review findings on stale r…
gabemontero Jul 30, 2026
f940316
fix(boost): RHDHPLAN-1505 address Marek review — namespace, packages,…
gabemontero Jul 30, 2026
4c91e4c
fix(boost): RHDHPLAN-1505 align on ai-catalog.providers namespace acr…
gabemontero Jul 30, 2026
d044e71
fix(boost): RHDHPLAN-1505 replace @boost/* with @red-hat-developer-hu…
gabemontero Jul 30, 2026
107d83f
fix(boost): RHDHPLAN-1505 defer Issue 5 RBAC gating to Issue 26
gabemontero Jul 30, 2026
0879bcd
fix(boost): RHDHPLAN-1505 replace catalog: with ai-catalog: in YAML c…
gabemontero Jul 30, 2026
bbee83f
fix(boost): RHDHPLAN-1505 address Marek review — config note, audit s…
gabemontero Aug 3, 2026
45de34a
fix(boost): RHDHPLAN-1505 align line 96 in frontend-coverage with RHD…
gabemontero Aug 3, 2026
a051663
fix(boost): RHDHPLAN-1505 address fullsend review — tls.ca typo, tier…
gabemontero Aug 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Boost uses catalog entities as the primary source of truth for AI domain objects

### Decision 4: toolscope extraction as standalone npm package

The toolscope subsystem (29 files) has zero Backstage dependencies. Packaged as `@boost/toolscope` with injectable `CacheAdapter` interface — default in-memory adapter for standalone use, Backstage adapter wrapping `coreServices.cache`.
The toolscope subsystem (29 files) has zero Backstage dependencies. Packaged as `@red-hat-developer-hub/backstage-plugin-boost-toolscope` with injectable `CacheAdapter` interface — default in-memory adapter for standalone use, Backstage adapter wrapping `coreServices.cache`.

### Decision 5: 4-stage lifecycle with ownership

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Entity providers are independently deployable as RHDH dynamic plugins — teams

### Toolscope as Standalone Package

- `@boost/toolscope` with zero Backstage dependencies (29 files)
- `@red-hat-developer-hub/backstage-plugin-boost-toolscope` with zero Backstage dependencies (29 files)
- Injectable `CacheAdapter` interface — default in-memory adapter for standalone use, Backstage adapter wrapping `coreServices.cache`

### Skills Marketplace Integration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@

## 3. Toolscope Package (P2)

- [ ] 3.1 Create `@boost/toolscope` package (29 files, zero Backstage dependencies)
- [ ] 3.1 Create `@red-hat-developer-hub/backstage-plugin-boost-toolscope` package (29 files, zero Backstage dependencies)
- [ ] 3.2 Define `CacheAdapter` interface for embedding and session caches
- [ ] 3.3 Create default in-memory `CacheAdapter` for standalone use
- [ ] 3.4 Create Backstage `CacheAdapter` wrapping `coreServices.cache`
- [ ] 3.5 Import `@boost/toolscope` from `boost-backend`
- [ ] 3.5 Import `@red-hat-developer-hub/backstage-plugin-boost-toolscope` from `boost-backend`

## 4. Lifecycle Model (P1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ This mapping is documented for reference — connectors MAY map differently base

### Decision 2: SDK package scope and structure

Single npm package `@boost/entity-provider-sdk` exports:
Single npm package `@red-hat-developer-hub/backstage-plugin-boost-entity-provider-sdk` exports:

- Provider interface types (`AIAssetEntityProvider`, entity emission contract)
- Annotation constants (`AI_ASSET_CATEGORY_ANNOTATION`, `AI_ASSET_VERSION_ANNOTATION`, `AI_ASSET_SOURCE_ANNOTATION`)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Boost builds this as a foundational layer: a standardized annotation scheme, a s
- Shared validation utilities rejecting entities with missing/invalid annotations
- Neo4j sync adapter interface for knowledge graph integration
- SkillBundle metadata contract for skillcard.yaml schema
- Published npm package (`@boost/entity-provider-sdk`)
- Published npm package (`@red-hat-developer-hub/backstage-plugin-boost-entity-provider-sdk`)

### Delta Sync Framework

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ Reference app-config YAML, Helm values, and Operator CR examples MUST be provide
global:
dynamic:
plugins:
- package: '@boost/plugin-boost-backend-module-kagenti'
- package: '@red-hat-developer-hub/backstage-plugin-boost-backend-module-kagenti'
disabled: false
boost:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ All AI asset entities MUST carry the `rhdh.io/ai-asset-version` annotation with

#### Scenario: SDK exports normalizeAIAssetVersion utility (RHIDP-15255)

- **WHEN** a developer imports `normalizeAIAssetVersion` from `@boost/entity-provider-sdk`
- **WHEN** a developer imports `normalizeAIAssetVersion` from `@red-hat-developer-hub/backstage-plugin-boost-entity-provider-sdk`
- **THEN** it is a function accepting `sourceVersion: string` and returning normalized semver string
- **AND** it implements all four normalization rules (semver pass-through, date-based, commit hash, fallback)
- **AND** unit tests cover all normalization rules
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The SDK MUST define TypeScript interfaces for AI asset entity providers covering
#### Scenario: AIAssetEntityProvider interface definition (RHIDP-15259)

- **WHEN** a developer implements an AI asset entity provider
- **THEN** they implement the `AIAssetEntityProvider` interface from `@boost/entity-provider-sdk`
- **THEN** they implement the `AIAssetEntityProvider` interface from `@red-hat-developer-hub/backstage-plugin-boost-entity-provider-sdk`
- **AND** the interface requires methods: `connect()`, `* entities()` (async generator), `getProviderName()`, `getProviderId()`
- **AND** the interface supports both full-refresh and incremental-sync patterns (incremental via optional `delta()` method)

Expand Down Expand Up @@ -51,13 +51,13 @@ The SDK MUST be published as an installable npm package with shared validation u

#### Scenario: SDK package is installable (RHIDP-15260)

- **WHEN** a developer runs `npm install @boost/entity-provider-sdk`
- **WHEN** a developer runs `npm install @red-hat-developer-hub/backstage-plugin-boost-entity-provider-sdk`
- **THEN** the package installs successfully
- **AND** the package exports: `AIAssetEntityProvider`, `AIAssetCategory`, annotation constants, `validateAIAssetEntity()`, `normalizeAIAssetVersion()`

#### Scenario: Annotation constants exported (RHIDP-15260)

- **WHEN** a developer imports from `@boost/entity-provider-sdk`
- **WHEN** a developer imports from `@red-hat-developer-hub/backstage-plugin-boost-entity-provider-sdk`
- **THEN** they can use constants: `AI_ASSET_CATEGORY_ANNOTATION = 'rhdh.io/ai-asset-category'`, `AI_ASSET_VERSION_ANNOTATION = 'rhdh.io/ai-asset-version'`, `AI_ASSET_SOURCE_ANNOTATION = 'rhdh.io/ai-asset-source'`

#### Scenario: Shared validation rejects invalid entities (RHIDP-15260)
Expand All @@ -81,7 +81,7 @@ The SDK MUST define a TypeScript interface for Neo4j sync adapters with node/rel
#### Scenario: Neo4jSyncAdapter interface definition (RHIDP-15303)

- **WHEN** a developer implements a Neo4j sync adapter
- **THEN** they implement the `Neo4jSyncAdapter` interface from `@boost/entity-provider-sdk`
- **THEN** they implement the `Neo4jSyncAdapter` interface from `@red-hat-developer-hub/backstage-plugin-boost-entity-provider-sdk`
- **AND** the interface requires methods: `createNode()`, `updateNode()`, `deleteNode()`, `createRelationship()`

#### Scenario: Relationship type constants (RHIDP-15303)
Expand All @@ -102,7 +102,7 @@ The SDK MUST define the TypeScript type for SkillBundle metadata (skillcard.yaml
#### Scenario: SkillBundleMetadata type definition (RHIDP-15303)

- **WHEN** a developer parses a `skillcard.yaml` file
- **THEN** they use the `SkillBundleMetadata` type from `@boost/entity-provider-sdk`
- **THEN** they use the `SkillBundleMetadata` type from `@red-hat-developer-hub/backstage-plugin-boost-entity-provider-sdk`
- **AND** the type defines fields: `name: string`, `version: string`, `description?: string`, `author?: string`, `tags?: string[]`, `runtime?: { language: string, dependencies?: Record<string, string> }`, `mcp?: { servers: string[] }`

#### Scenario: OCI skill registry uses SkillBundleMetadata (RHIDP-15303)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

> **Cross-connector dependencies:** RHIDP-15260 is blocked by RHIDP-15265 (endpoint/credential config schema), RHIDP-15329 (shared CA bundle utility), and RHIDP-15330 (error isolation contract). The SDK must export the configuration schema, CA bundle utility, and error-handling guarantees defined by those stories.

- [ ] 2.1 Create `@boost/entity-provider-sdk` package with `package.json`, `tsconfig.json`, `README.md`, `CHANGELOG.md` (RHIDP-15260)
- [ ] 2.1 Create `@red-hat-developer-hub/backstage-plugin-boost-entity-provider-sdk` package with `package.json`, `tsconfig.json`, `README.md`, `CHANGELOG.md` (RHIDP-15260)
- [ ] 2.2 Define `AIAssetEntityProvider` TypeScript interface with required methods: `connect()`, `* entities()`, `getProviderName()`, `getProviderId()` (RHIDP-15259)
- [ ] 2.3 Define optional `delta(cursor?: string)` method for incremental sync pattern (RHIDP-15259)
- [ ] 2.4 Export annotation constants: `AI_ASSET_CATEGORY_ANNOTATION`, `AI_ASSET_VERSION_ANNOTATION`, `AI_ASSET_SOURCE_ANNOTATION` (RHIDP-15260)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ import {
CA bundles are loaded from mounted file paths or K8s Secret references. The config schema supports both patterns:

```yaml
catalog:
ai-catalog:
providers:
mcpRegistry:
tls:
Expand All @@ -76,8 +76,8 @@ function loadCaBundle(connectorConfig: Config): Buffer | undefined;

The caller passes the Config subtree that contains the `tls` block. This allows each connector to resolve its own config nesting before calling the shared utility:

- MCP Registry: `loadCaBundle(config.getConfig('catalog.providers.mcpRegistry'))`
- RHOAI MCP Catalog: `loadCaBundle(config.getConfig('catalog.providers.rhoai.mcpCatalog'))`
- MCP Registry: `loadCaBundle(config.getConfig('ai-catalog.providers.mcpRegistry'))`
- RHOAI MCP Catalog: `loadCaBundle(config.getConfig('ai-catalog.providers.rhoai.mcpCatalog'))`
- OCI per-registry: `loadCaBundle(registryConfig)` where `registryConfig` is the per-registry Config node

**Behavior:**
Expand All @@ -93,7 +93,7 @@ The caller passes the Config subtree that contains the `tls` block. This allows
**Integration with HTTP client:**

```typescript
const connectorConfig = config.getConfig('catalog.providers.mcpRegistry');
const connectorConfig = config.getConfig('ai-catalog.providers.mcpRegistry');
const caBundle = loadCaBundle(connectorConfig);
const agent = caBundle ? new https.Agent({ ca: caBundle }) : undefined;

Expand Down Expand Up @@ -167,12 +167,12 @@ export function createSafeRefresh(

### Decision 4: Enable/disable pattern

Each connector checks `catalog.providers.<connectorId>.enabled` at backend module initialization. Disabled connectors are never registered — they produce zero resource usage.
Each connector checks `ai-catalog.providers.<connectorId>.enabled` at backend module initialization. Disabled connectors are never registered — they produce zero resource usage.

**Config schema:**

```yaml
catalog:
ai-catalog:
providers:
mcpRegistry:
enabled: true # Default: true if omitted
Expand All @@ -198,7 +198,7 @@ export default createBackendModule({
},
async init({ catalog, config, logger }) {
const connectorConfig = config.getConfig(
'catalog.providers.mcpRegistry',
'ai-catalog.providers.mcpRegistry',
);
if (!isConnectorEnabled(connectorConfig)) {
logger.info('MCP Registry connector is disabled');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Duplicating CA/TLS handling, error logging, and enable/disable config across eac
### CA Bundle Resolution Utility

- `loadCaBundle(connectorConfig: Config): Buffer | undefined` function — caller passes the Config subtree containing the `tls` block
- Caller resolves config nesting before calling: e.g., `config.getConfig('catalog.providers.mcpRegistry')` for MCP, `config.getConfig('catalog.providers.rhoai.mcpCatalog')` for RHOAI, per-registry Config node for OCI
- Caller resolves config nesting before calling: e.g., `config.getConfig('ai-catalog.providers.mcpRegistry')` for MCP, `config.getConfig('ai-catalog.providers.rhoai.mcpCatalog')` for RHOAI, per-registry Config node for OCI
- Reads CA bundles from K8s Secret/ConfigMap mounts or direct file paths
- Creates `https.Agent` with custom CA for HTTP client injection
- Handles missing/invalid CA gracefully: log warning, return undefined, don't crash provider
Expand All @@ -26,7 +26,7 @@ Duplicating CA/TLS handling, error logging, and enable/disable config across eac

### Enable/Disable Pattern

- `catalog.providers.<connectorId>.enabled: true/false` config schema
- `ai-catalog.providers.<connectorId>.enabled: true/false` config schema
- Registration guard: skip `catalog.addEntityProvider()` when disabled
- Disabled connector produces zero resource usage (no scheduled tasks created)
- Consistent pattern across all three connectors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ Each connector can configure a custom CA bundle for HTTPS verification via confi

#### Scenario: CA loaded from file path

- **WHEN** a connector is configured with `catalog.providers.<connectorId>.tls.caFile: /etc/ssl/certs/custom-ca.pem` (must be an absolute path)
- **WHEN** a connector is configured with `ai-catalog.providers.<connectorId>.tls.caFile: /etc/ssl/certs/custom-ca.pem` (must be an absolute path)
- **THEN** `loadCaBundle(connectorConfig)` reads the PEM file from the `tls.caFile` path within the provided Config subtree
- **AND** returns a `Buffer` containing the CA certificate(s)
- **AND** the connector uses this buffer to create an `https.Agent` with custom CA

#### Scenario: CA loaded from K8s Secret mount

- **WHEN** a connector is configured with `catalog.providers.<connectorId>.tls.caSecret.$env: CONNECTOR_CA_BUNDLE`
- **WHEN** a connector is configured with `ai-catalog.providers.<connectorId>.tls.caSecret.$env: CONNECTOR_CA_BUNDLE`
- **THEN** `loadCaBundle()` reads the PEM content from the environment variable `CONNECTOR_CA_BUNDLE`
- **AND** returns a `Buffer` containing the CA certificate(s)
- **AND** the environment variable is populated by K8s via Secret mount (operator responsibility)
Expand All @@ -28,8 +28,8 @@ Each connector can configure a custom CA bundle for HTTPS verification via confi

- **WHEN** MCP Registry connector has `tls.caFile: /etc/ssl/mcp-ca.pem`
- **AND** RHOAI connector has `tls.caFile: /etc/ssl/rhoai-ca.pem`
- **THEN** `loadCaBundle(mcpRegistryConfig)` returns only the MCP Registry CA bundle (where `mcpRegistryConfig = config.getConfig('catalog.providers.mcpRegistry')`)
- **AND** `loadCaBundle(rhoaiMcpCatalogConfig)` returns only the RHOAI CA bundle (where `rhoaiMcpCatalogConfig = config.getConfig('catalog.providers.rhoai.mcpCatalog')`)
- **THEN** `loadCaBundle(mcpRegistryConfig)` returns only the MCP Registry CA bundle (where `mcpRegistryConfig = config.getConfig('ai-catalog.providers.mcpRegistry')`)
- **AND** `loadCaBundle(rhoaiMcpCatalogConfig)` returns only the RHOAI CA bundle (where `rhoaiMcpCatalogConfig = config.getConfig('ai-catalog.providers.rhoai.mcpCatalog')`)
- **AND** each connector's `https.Agent` uses its own CA, not the other connector's CA

### Requirement: Graceful Failure Handling
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Disabled connectors are never registered, producing zero resource usage.

#### Scenario: Disabled connector produces zero resource usage

- **WHEN** a connector is configured with `catalog.providers.<connectorId>.enabled: false`
- **WHEN** a connector is configured with `ai-catalog.providers.<connectorId>.enabled: false`
- **THEN** `isConnectorEnabled(connectorConfig)` returns `false` (where `connectorConfig` is the connector's Config subtree)
- **AND** the backend module's `init()` exits early without calling `catalog.addEntityProvider()`
- **AND** no scheduled tasks are created for the disabled connector
Expand All @@ -72,7 +72,7 @@ Disabled connectors are never registered, producing zero resource usage.

#### Scenario: Enabled connector registered normally

- **WHEN** a connector is configured with `catalog.providers.<connectorId>.enabled: true`
- **WHEN** a connector is configured with `ai-catalog.providers.<connectorId>.enabled: true`
- **OR** the `enabled` field is omitted (defaults to `true`)
- **THEN** `isConnectorEnabled(connectorConfig)` returns `true`
- **AND** the backend module proceeds with provider registration via `catalog.addEntityProvider()`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The reference YAML must demonstrate MCP Registry connector configuration fields.
- **WHEN** a deployer configures the MCP Registry connector for an air-gapped environment
- **THEN** the reference YAML includes:
```yaml
catalog:
ai-catalog:
providers:
mcpRegistry:
# Mirror endpoint overrides public registry.modelcontextprotocol.io
Expand All @@ -49,7 +49,7 @@ The reference YAML must demonstrate RHOAI connector configuration fields.
- **WHEN** a deployer configures the RHOAI connector for a separate AI cluster
- **THEN** the reference YAML includes:
```yaml
catalog:
ai-catalog:
providers:
rhoai:
mcpCatalog:
Expand Down Expand Up @@ -78,7 +78,7 @@ The reference YAML must demonstrate OCI Skill connector configuration fields.
- **WHEN** a deployer configures the OCI Skill connector for multiple registries
- **THEN** the reference YAML includes:
```yaml
catalog:
ai-catalog:
providers:
ociSkill:
enabled: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
- [ ] 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.5 Add per-connector config isolation — each connector resolves its own Config nesting before calling `loadCaBundle()` (e.g., MCP passes `config.getConfig('ai-catalog.providers.mcpRegistry')`, RHOAI passes `config.getConfig('ai-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 WARN-level warning with expected file path, return `undefined` (don't crash)
- [ ] 1.8 Handle invalid/expired CA certificate: log ERROR with certificate details (issuer, expiry), return `undefined`
Expand Down Expand Up @@ -34,7 +34,7 @@

## 3. Enable/Disable Pattern (P0) — RHIDP-15330

- [ ] 3.1 Define enable/disable config schema in README: `catalog.providers.<id>.enabled: boolean`
- [ ] 3.1 Define enable/disable config schema in README: `ai-catalog.providers.<id>.enabled: boolean`
- [ ] 3.2 Create `isConnectorEnabled(connectorConfig: Config): boolean` utility — caller passes the Config subtree (same pattern as `loadCaBundle`)
- [ ] 3.3 Implement config reader: read `enabled` from the provided Config subtree, return `true` if omitted (default enabled)
- [ ] 3.4 Create registration guard pattern for backend module `init()` example in README
Expand Down Expand Up @@ -75,11 +75,13 @@
- [ ] 6.6 Add air-gapped deployment variant showing zero-internet configuration
- [ ] 6.7 Place reference YAML in `workspaces/boost/examples/` or alongside connector README files

## 7. Connector Integration (P2)
## ~~7. Connector Integration (P2) — deferred~~

- [ ] 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
~~These tasks require connectors that are created in Tier 1 (Issues 9–16). Each connector issue will consume `boost-connector-utils` as part of its own implementation. See Issues 9 (OCI), 13–14 (MCP Registry), 15–16 (RHOAI).~~

- ~~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~~
Loading
Loading