From 37816e965fd47441339c500d1670030c8bae02c4 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 4 Jun 2026 10:34:21 -0400 Subject: [PATCH 1/8] docs(boost): address review feedback on PRD and OpenSpec specifications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review feedback from colleague: - [medium] PNG diagram references: Remove references to use case and architecture diagram PNGs from augment workspace (not applicable to boost clean-room reimplementation) - [medium] Augment plugin naming: Change forward-looking spec scenarios from "augment plugin" to "boost plugin" where describing boost's own future behavior - [low] UC numbering gap: Add note in AI Chat PRD explaining UC-4 is defined in Agent Creation & Discovery PRD - [medium] Spec status: Mark all 23 specs as "Status: Draft" and add status: draft to .openspec.yaml files to set expectations - [medium] naming-convention: Fix singular "workspace" to plural "workspaces" in 7+ path references - [medium] none alias contradiction: Align task 10.8 with task 9.2's no-legacy-aliases stance - [low] Permission count mismatch: Update proposal from "7-9" to "16" fine-grained permissions - [low] Pending lifecycle mapping: Add Pending → experimental mapping - [low] Number inconsistencies: Fix cache count (14→17) and validator lines (668→671) in platform-operations-deployment proposal - [medium] Missing ADR/README: Update README.md with project rationale and directory structure documentation Additional changes driven by review discussion: - Pivot all proposal/design/task documents from augment migration framing to boost clean-room implementation ("What Boost Builds" instead of "Current Capabilities" + "Architectural Improvements") - Remove "Replace X with Y" / "Migrate X to Y" task language in favor of "Implement Y from the start" - Replace augment file paths (plugins/augment-backend/) with boost paths (plugins/boost-backend/) throughout - Rename all augment-namespaced identifiers to boost: config keys (augment.* → boost.*), permissions (augment.agent.* → boost.agent.*), DB tables (augment_feedback → boost_feedback), plugin registration (augmentPlugin → boostPlugin), service refs (augmentAiProviderServiceRef → boostAiProviderServiceRef), package names (@augment/* → @boost/*), resource types (augment-agent → boost-agent), extension points (augmentProviderExtensionPoint → boostProviderExtensionPoint), pluginId ('augment' → 'boost'), and OCI artifact names - Replace @augment-adk/augment-adk references with OpenAI Agent SDK (via Llama Stack Responses API), reflecting augment's move away from the ADK library Signed-off-by: gabemontero Co-Authored-By: Claude Opus 4.6 --- .../agent-creation-discovery/design.md | 22 ++--- .../agent-creation-discovery/proposal.md | 62 ++++++++++---- .../specs/catalog-entities/spec.md | 8 +- .../changes/agent-creation-discovery/tasks.md | 30 ++++--- .../ai-chat-interaction-experience/design.md | 20 ++--- .../proposal.md | 57 ++++++++----- .../specs/conversation-history/spec.md | 4 +- .../specs/frontend-composability/spec.md | 12 +-- .../ai-chat-interaction-experience/tasks.md | 2 +- .../platform-operations-deployment/design.md | 38 ++++----- .../proposal.md | 80 ++++++++++++++----- .../specs/cache-migration/spec.md | 70 +++++++--------- .../specs/deployment/spec.md | 2 +- .../specs/runtime-config/spec.md | 20 ++--- .../platform-operations-deployment/tasks.md | 13 ++- .../design.md | 74 ++++++++--------- .../proposal.md | 60 +++++++++----- .../specs/multi-agent-orchestration/spec.md | 12 +-- .../specs/provider-abstraction/spec.md | 18 ++--- .../specs/provider-packaging/spec.md | 18 ++--- .../tasks.md | 80 +++++++++---------- .../security-safety-governance/design.md | 14 ++-- .../security-safety-governance/proposal.md | 53 +++++++----- .../specs/access-control/spec.md | 26 +++--- .../specs/fine-grained-permissions/spec.md | 54 ++++++------- .../security-safety-governance/tasks.md | 62 +++++++------- .../boost/specifications/boost-context.md | 6 +- .../prd/agent-creation-discovery.md | 2 +- .../prd/ai-chat-interaction-experience.md | 8 +- .../prd/platform-operations-deployment.md | 12 +-- .../prd/pluggable-ai-platform-architecture.md | 30 +++---- .../prd/security-safety-governance.md | 54 ++++++------- 32 files changed, 558 insertions(+), 465 deletions(-) diff --git a/workspaces/boost/openspec/changes/agent-creation-discovery/design.md b/workspaces/boost/openspec/changes/agent-creation-discovery/design.md index 43574b865c9..f528585e3b3 100644 --- a/workspaces/boost/openspec/changes/agent-creation-discovery/design.md +++ b/workspaces/boost/openspec/changes/agent-creation-discovery/design.md @@ -2,7 +2,7 @@ ## Context -Boost models AI domain objects (agents, tools, models, MCP servers, vector stores) as Backstage catalog entities from the start, informed by augment's experience. Augment managed these entirely in plugin-internal caches — four separate in-memory stores with duplicate caches, no discoverability, and no catalog-level RBAC. Boost uses catalog entity providers from day one, with existing Backstage kinds (`Component`, `Resource`) and a migration path to upstream `AIContext` and `API v1alpha2` kinds when available. +Boost models AI domain objects (agents, tools, models, MCP servers, vector stores) as Backstage catalog entities from the start. The Augment reference prototype managed these entirely in plugin-internal caches; boost uses catalog entity providers from day one, with existing Backstage kinds (`Component`, `Resource`) and a path to upstream `AIContext` and `API v1alpha2` kinds when available. Boost implements the 4-stage agent lifecycle (Draft → Pending → Published → Archived) from the start — no legacy stage mappings needed. @@ -10,9 +10,9 @@ Boost integrates with an external skills marketplace (provided by a separate wor ## Goals -- AI domain objects as Backstage catalog entities from day one (using existing kinds with upstream migration path) +- AI domain objects as Backstage catalog entities from day one (using existing kinds with upstream kind path) - No in-memory caches for domain objects — catalog is the source of truth -- Entity providers packaged as an independent RHDH dynamic plugin module +- Entity providers packaged as independent RHDH dynamic plugin modules - Toolscope as a standalone package with injectable cache adapter - 4-stage lifecycle model with ownership semantics from the start - Integration with external skills marketplace for agent discovery and deployment @@ -25,9 +25,9 @@ Boost integrates with an external skills marketplace (provided by a separate wor ## Decisions -### Decision 1: Use existing kinds with fallback to upstream +### Decision 1: Use existing kinds with path to upstream -Use `kind: Component, spec.type: ai-agent` for agents and `kind: Resource, spec.type: ai-model|mcp-server|vector-store|ai-tool` for infrastructure resources. When upstream `AIContext` and `API v1alpha2` land, migrate to those kinds. Custom `CatalogProcessor` validators support both during transition. Tools are added as `kind: Resource, spec.type: ai-tool` to enable tool lifecycle permissions via catalog RBAC. +Use `kind: Component, spec.type: ai-agent` for agents and `kind: Resource, spec.type: ai-model|mcp-server|vector-store|ai-tool` for infrastructure resources. When upstream `AIContext` and `API v1alpha2` land, adopt those kinds. Custom `CatalogProcessor` validators support both during transition. Tools are added as `kind: Resource, spec.type: ai-tool` to enable tool lifecycle permissions via catalog RBAC. ### Decision 2: Entity providers as independently deployable backend services @@ -43,13 +43,13 @@ Entity providers are separate packages registered as Backstage backend services, Packages live at `rhdh-plugins/workspaces/boost/plugins/llamastack-entity-provider` and `kagenti-entity-provider`. -### Decision 3: Gradual cache elimination +### Decision 3: Catalog as source of truth from the start -Phase 1: EntityProviders emit entities alongside existing caches (dual-write). Phase 2: Frontend/backend consumers switch to catalog API queries. Phase 3: Remove in-memory caches. This avoids a big-bang migration. +Boost uses catalog entities as the primary source of truth for AI domain objects. There is no dual-write phase — entity providers emit entities directly and frontend/backend consumers query the catalog API. ### Decision 4: toolscope extraction as standalone npm package -The `services/toolscope/` subsystem (29 files) has zero Backstage dependencies. Extracted as `@augment/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 `@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 @@ -57,10 +57,10 @@ Agents follow the 4-stage lifecycle from the start: Draft → Pending → Publis ### Decision 6: Skills marketplace integration (consumer only) -Augment integrates with an external skills marketplace provided by a separate workspace. Augment proxies browse/filter requests to the external catalog and owns only the deployment side: K8s manifest generation with OCI init containers, namespace scoping, and deployment progress tracking. Deployed skills carry `framework: 'docsclaw'` and `chatEndpoint` for direct routing. Deployed skills appear in the gallery with a skill badge. Skills catalog entities will eventually be emitted by the catalog module alongside other agent entities. +Boost integrates with an external skills marketplace provided by a separate workspace. Boost proxies browse/filter requests to the external catalog and owns only the deployment side: K8s manifest generation with OCI init containers, namespace scoping, and deployment progress tracking. Deployed skills carry `framework: 'docsclaw'` and `chatEndpoint` for direct routing. Deployed skills appear in the gallery with a skill badge. Skills catalog entities will eventually be emitted by the catalog module alongside other agent entities. ## Risks - **Catalog polling latency vs. cache TTL:** Catalog entities update on provider schedules, not on-demand. Mitigated by keeping short poll intervals for models (60s) and offering manual refresh. -- **Upstream kind availability:** `AIContext` may not be ready. Mitigated by starting with existing kinds and designing for migration. -- **Upstream augment data import:** If boost ever needs to import agent data from augment, a one-time migration script would map 5-stage values to 4-stage. This is not a runtime concern. +- **Upstream kind availability:** `AIContext` may not be ready. Mitigated by starting with existing kinds and designing for smooth adoption. +- **Upstream augment data import:** If boost ever needs to import agent data from augment, a one-time script would map augment's stage values to boost's 4-stage model. This is not a runtime concern. diff --git a/workspaces/boost/openspec/changes/agent-creation-discovery/proposal.md b/workspaces/boost/openspec/changes/agent-creation-discovery/proposal.md index fc7bde2327f..d0667db04b9 100644 --- a/workspaces/boost/openspec/changes/agent-creation-discovery/proposal.md +++ b/workspaces/boost/openspec/changes/agent-creation-discovery/proposal.md @@ -2,31 +2,59 @@ ## Why -An agentic AI platform is only as valuable as its agents. Augment supports four creation paths (no-code, template, DevSpaces, import), a gallery for discovery, and MCP tool connectivity. These form the supply side of the agent ecosystem. +An agentic AI platform is only as valuable as its agents. Boost supports four creation paths (no-code, template, DevSpaces, import), a gallery for discovery, and MCP tool connectivity. These form the supply side of the agent ecosystem. -The current implementation manages agents, MCP servers, and models entirely within plugin-internal caches and databases. These domain objects are natural candidates for Backstage catalog entities, which would provide discoverability, ownership, lifecycle management, and catalog-level RBAC — capabilities the current approach cannot offer. +Boost models agents, MCP servers, models, and other AI domain objects as Backstage catalog entities from the start, providing discoverability, ownership, lifecycle management, and catalog-level RBAC that plugin-internal caches cannot offer. -## What Changes +## What Boost Builds -### Current Capabilities (retroactive documentation) +### Agent Gallery & Discovery - Browse and select agents via gallery (Kagenti) or router delegation (Llama Stack) -- Four agent creation paths: no-code builder, Software Template, DevSpaces, import -- MCP tool server registration with 4-level auth chain -- Agent lifecycle: draft → registered → deployed (published=true) - Unified `ChatAgent` model merging agents from all providers -### Architectural Improvements (from tech debt analysis) +### Agent Creation Paths + +- Four creation paths: no-code builder, Software Template, DevSpaces, import +- All paths produce agents visible in the gallery and available in chat + +### MCP Tool Connectivity + +- MCP tool server registration with 4-level auth chain +- Per-agent tool scoping via configuration + +### Catalog Entity Providers + +- `EntityProvider` for AI agents (maps to upstream `AIContext` initiative; uses `kind: Component, spec.type: ai-agent` until upstream kinds land) +- `EntityProvider` for AI models (`kind: Resource, spec.type: ai-model`) +- `EntityProvider` for MCP servers (maps to upstream `API Discriminated Union v1alpha2`; uses `kind: Resource, spec.type: mcp-server`) +- `EntityProvider` for vector stores (`kind: Resource, spec.type: vector-store`) +- `EntityProvider` for AI tools (`kind: Resource, spec.type: ai-tool`) + +Entity providers are independently deployable as RHDH dynamic plugins — teams using Llama Stack or Kagenti can get catalog discoverability without installing the full boost plugin. + +### 4-Stage Agent Lifecycle + +- Draft → Pending → Published → Archived from day one +- `createdBy` ownership drives visibility filtering, action gating, and self-approval prevention +- Cascading delete detects agent source and cleans up across corresponding stores + +### Toolscope as Standalone Package + +- `@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 -- Create catalog `EntityProvider` for AI agents (maps to upstream `AIContext` initiative) -- Create catalog `EntityProvider` for MCP servers (maps to upstream `API Discriminated Union v1alpha2`) -- Create catalog `EntityProvider` for AI models (currently duplicated in caches #3 and #4) -- Create catalog `EntityProvider` for vector stores -- Extract `toolscope/` as standalone package (zero Backstage dependencies) +- Consumer of external skills marketplace (provided by a separate workspace) +- Proxy browse/filter requests to external catalog +- K8s manifest generation with OCI init containers for skill deployment ## Impact -- New: `plugin-augment-backend-module-catalog-agents` (EntityProvider for agents) -- New: `plugin-augment-backend-module-catalog-mcp` (EntityProvider for MCP servers) -- `plugins/augment-backend/src/providers/` — remove agent card and model caches in favor of catalog -- `plugins/augment-backend/src/services/toolscope/` — extract as standalone package +- `plugins/boost-backend/` — entity providers for MCP servers and vector stores (cross-cutting) +- `plugins/boost-backend-module-kagenti/` — composes `kagenti-entity-provider` internally +- `plugins/boost-backend-module-llamastack/` — composes `llamastack-entity-provider` internally +- New: `plugins/kagenti-entity-provider/` — independently deployable catalog entities +- New: `plugins/llamastack-entity-provider/` — independently deployable catalog entities +- New: `packages/toolscope/` — standalone toolscope package diff --git a/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md b/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md index 2a8bae60565..2aa8b64fb10 100644 --- a/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md +++ b/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md @@ -9,7 +9,7 @@ NOTE: These recommendations align with in-flight upstream Backstage initiatives: - `AIContext`: Agent Cards will map to this kind when available - `API Discriminated Union v1alpha2`: MCP Servers and AI Model Servers will map to the expanded `API` kind when available -The specifications below use existing Backstage kinds (`Resource`, `Component`) as the primary implementation path, with migration to upstream kinds when they land. Custom `CatalogProcessor` validators support both during transition. +The specifications below use existing Backstage kinds (`Resource`, `Component`) as the primary implementation path, with adoption of upstream kinds when they land. Custom `CatalogProcessor` validators support both during transition. **Entity type strategy:** | Domain Object | Immediate Kind | `spec.type` | Future Kind (upstream) | @@ -41,7 +41,7 @@ Agents are represented as Backstage catalog entities with lifecycle, ownership, - **THEN** it polls the Kagenti API for all agents across configured namespaces - **AND** it emits catalog entities with `kind: Component, spec.type: ai-agent` (or `kind: AIContext` when upstream is available) - **AND** agent capabilities, LLM demands, and MCP demands map to `spec.dependsOn` relations -- **AND** the entity replaces the in-memory `KagentiAgentCardCache` (cache #2) +- **AND** the catalog is the source of truth for agent data — no in-memory cache needed #### Scenario: Llama Stack module emits agent entities @@ -53,7 +53,7 @@ Agents are represented as Backstage catalog entities with lifecycle, ownership, - **WHEN** an agent transitions through lifecycle stages (Draft → Pending → Published → Archived) - **THEN** the catalog entity's `metadata.annotations` reflect the current 4-stage lifecycle stage -- **AND** catalog entity lifecycle state maps: Draft → `experimental`, Published → `production`, Archived → `deprecated` +- **AND** catalog entity lifecycle state maps: Draft → `experimental`, Pending → `experimental`, Published → `production`, Archived → `deprecated` - **AND** `createdBy` ownership maps to catalog entity `spec.owner` for RBAC integration ### Requirement: AI Model Catalog Entities @@ -106,7 +106,7 @@ Entity providers are independently deployable Backstage backend services. - **WHEN** a boost provider module (e.g., `plugin-boost-backend-module-kagenti`) is installed - **THEN** it composes the `kagenti-entity-provider` package internally -- **AND** it registers both AI capabilities (via `augmentProviderExtensionPoint`) and catalog entities (via `catalogProcessingExtensionPoint`) +- **AND** it registers both AI capabilities (via `boostProviderExtensionPoint`) and catalog entities (via `catalogProcessingExtensionPoint`) - **AND** installing the provider module gives you both AI capabilities and catalog entities in one step #### Scenario: Cross-cutting entity providers in core plugin diff --git a/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md b/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md index 9a4f95642e5..f052d77c5de 100644 --- a/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md +++ b/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md @@ -22,8 +22,8 @@ ### 1c. Composition into boost provider modules -- [ ] 1c.1 `plugin-boost-backend-module-kagenti` composes `kagenti-entity-provider` internally -- [ ] 1c.2 `plugin-boost-backend-module-llamastack` composes `llamastack-entity-provider` internally +- [ ] 1c.1 `boost-backend-module-kagenti` composes `kagenti-entity-provider` internally +- [ ] 1c.2 `boost-backend-module-llamastack` composes `llamastack-entity-provider` internally - [ ] 1c.3 Verify composed deployment: provider module install gives AI capabilities + catalog entities ### 1d. Core plugin entity providers (cross-cutting) @@ -35,26 +35,24 @@ ### 1e. Shared entity concerns - [ ] 1e.1 Map agent `createdBy` → catalog entity `spec.owner` for RBAC integration -- [ ] 1e.2 Map 4-stage lifecycle (Draft/Pending/Published/Archived) → catalog lifecycle state (experimental/production/deprecated) in entity annotations +- [ ] 1e.2 Map 4-stage lifecycle (Draft/Pending/Published/Archived) → catalog lifecycle state (experimental/experimental/production/deprecated) in entity annotations - [ ] 1e.3 Create `CatalogProcessor` validators for ai-agent, ai-model, mcp-server, vector-store, ai-tool types - [ ] 1e.4 Configure scheduled task runners per provider (60s models, 5m agents/MCP/tools, 10m vector stores) -## 2. Catalog Migration (P2) +## 2. Catalog Integration (P2) -- [ ] 2.1 Add catalog API queries alongside existing cache reads (dual-read phase) -- [ ] 2.2 Update `useAgentGalleryData` to optionally read from catalog API -- [ ] 2.3 Update model list endpoints to read from catalog -- [ ] 2.4 Remove `KagentiAgentCardCache` (cache #2) after catalog migration -- [ ] 2.5 Remove `ResponsesApiProvider._modelsCache` (cache #3) and `KagentiProvider._modelsCache` (cache #4) after catalog migration -- [ ] 2.6 Remove `BackendToolExecutor` tool schema cache (cache #7) after catalog migration +- [ ] 2.1 Implement `useAgentGalleryData` reading from catalog API +- [ ] 2.2 Implement model list endpoints reading from catalog +- [ ] 2.3 Implement tool list endpoints reading from catalog +- [ ] 2.4 Verify all domain object queries go through catalog — no standalone in-memory caches -## 3. Toolscope Extraction (P2) +## 3. Toolscope Package (P2) -- [ ] 3.1 Create `@augment/toolscope` package from `services/toolscope/` (29 files) -- [ ] 3.2 Define `CacheAdapter` interface replacing raw `Map<>` in embedding and session caches +- [ ] 3.1 Create `@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 Update `augment-backend` to import from `@augment/toolscope` +- [ ] 3.5 Import `@boost/toolscope` from `boost-backend` ## 4. Lifecycle Model (P1) @@ -73,9 +71,9 @@ ## 6. Verify - [ ] 6.1 Verify catalog entities appear for agents, models, MCP servers, vector stores, and tools -- [ ] 6.2 Verify catalog-based agent gallery matches cache-based gallery +- [ ] 6.2 Verify catalog-based agent gallery displays correctly - [ ] 6.3 Verify agent `spec.owner` matches `createdBy` for RBAC -- [ ] 6.4 Verify lifecycle stage mapping: Draft→experimental, Published→production, Archived→deprecated +- [ ] 6.4 Verify lifecycle stage mapping: Draft→experimental, Pending→experimental, Published→production, Archived→deprecated - [ ] 6.5 Verify toolscope package works standalone (without Backstage) - [ ] 6.6 Verify toolscope package works with Backstage cacheService adapter - [ ] 6.7 Verify skills deployment creates correct K8s manifests diff --git a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/design.md b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/design.md index 0f3f04b6787..98aa04130d0 100644 --- a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/design.md +++ b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/design.md @@ -2,13 +2,13 @@ ## Context -The chat experience is fully functional but the frontend is monolithic. `AugmentPage` is the single routable extension, eagerly loading all 204 admin panel files and all provider-specific components. Sub-route refs already exist in `routes.ts` — the composability plumbing is partially there. +Boost builds the frontend as composable extensions from the start. The chat, admin, and agent studio are independently mountable routable extensions with lazy loading at extension boundaries. Sub-route refs are defined in `routes.ts` from day one. ## Goals -- Decompose into composable extensions using existing sub-route refs -- Add lazy loading in `ChatView.tsx` and `AdminLayout.tsx` -- Add config-driven feature flags via `app-config.yaml` +- Composable routable extensions for chat, admin, and agent studio +- Lazy loading via `React.lazy()` in `ChatView.tsx` and `AdminLayout.tsx` +- Config-driven feature flags via `app-config.yaml` - Register with Backstage `featureFlagsApiRef` ## Non-Goals @@ -16,27 +16,27 @@ The chat experience is fully functional but the frontend is monolithic. `Augment - Changing the streaming protocol or event processing - Modifying HITL approval flow behavior - Changing conversation persistence schema -- Migrating session caches (covered in platform-operations-deployment change) +- Session caches (covered in platform-operations-deployment change) ## Decisions ### Decision 1: Composable extensions wrap lazy-loaded components -Each new routable extension uses `React.lazy()` in its `component` factory. This means code-splitting happens at the extension boundary — deployers who mount only `AugmentChatPage` never download admin panel code. +Each routable extension uses `React.lazy()` in its `component` factory. This means code-splitting happens at the extension boundary — deployers who mount only `BoostChatPage` never download admin panel code. ### Decision 2: Feature flags use both Backstage API and app-config Two mechanisms work together: -- `app-config.yaml` `augment.features.*` keys provide deployer-controlled defaults +- `app-config.yaml` `boost.features.*` keys provide deployer-controlled defaults - Backstage `featureFlagsApiRef` allows runtime user-level overrides via Settings UI - The `useFeatureFlags` hook checks app-config first, then `featureFlagsApiRef` for overrides -### Decision 3: Existing AugmentPage preserved as composition root +### Decision 3: Default page preserved as composition root -The monolithic `AugmentPage` remains available and unchanged. New extensions are additive. Zero breaking changes for existing deployers. +A default `BoostPage` serves as the all-in-one composition root. New extensions are additive — deployers can mount individual extensions or use the default page that composes them all. ## Risks -- **Extension boundary state sharing:** Chat and admin extensions share `AugmentContext`. Mitigated by lifting shared state to a context provider registered at the plugin level, not the page level. +- **Extension boundary state sharing:** Chat and admin extensions share context. Mitigated by lifting shared state to a context provider registered at the plugin level, not the page level. - **Lazy loading SSR incompatibility:** Not a concern — RHDH is SPA-only. diff --git a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/proposal.md b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/proposal.md index d093e74163e..691c60c92c0 100644 --- a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/proposal.md +++ b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/proposal.md @@ -2,32 +2,49 @@ ## Why -Augment's core value is the developer-agent conversation interface. Without a compelling chat experience, the platform has no user-facing value regardless of backend configuration. The chat surface must deliver streaming responses, knowledge-grounded answers with citations, human-in-the-loop approval for sensitive actions, persistent conversation history, and developer debugging tools. +Boost's core value is the developer-agent conversation interface. Without a compelling chat experience, the platform has no user-facing value regardless of backend configuration. The chat surface must deliver streaming responses, knowledge-grounded answers with citations, human-in-the-loop approval for sensitive actions, persistent conversation history, and developer debugging tools. -The current implementation delivers all product capabilities but the frontend is monolithic — all 204 admin panel files and all provider-specific components are eagerly loaded for every user. The chat view needs composable extensions, lazy loading, and capability-driven rendering. +Boost builds the frontend as composable extensions from the start — chat, admin, and agent studio are independently mountable routable extensions with lazy loading and capability-driven rendering. -## What Changes +## What Boost Builds -### Current Capabilities (retroactive documentation) +### Streaming Chat -- Streaming chat with real-time phase indicators and rich markdown rendering -- Knowledge-grounded answers (RAG) with source citations and expandable source cards -- Human-in-the-loop approval for tool calls with parameter editing -- Interactive cards (forms, auth flows) within conversations -- Conversation history with search, resume, feedback, and export -- Developer tools: execution trace, session inspector, message inspector -- Provider-adaptive chat experience (Llama Stack vs Kagenti paths) +- Real-time streamed conversation with specialist AI agents +- Phase indicators, rich markdown rendering, and provider-adaptive behavior -### Architectural Improvements (from tech debt analysis) +### Knowledge-Grounded Answers (RAG) -- Lazy loading in `ChatView.tsx` for provider-specific components (204 admin panel files currently eagerly loaded) -- Split `AugmentPage` into composable routable extensions (chat, admin, agent studio) -- Capability-driven rendering replacing provider ID string checks -- Frontend feature flags via `app-config.yaml` and Backstage `featureFlagsApiRef` +- Answers grounded in organizational documentation with source citations +- Expandable source cards for traceability + +### Human-in-the-Loop Approval + +- Tool call approval with parameter editing before execution +- No destructive action executes without explicit developer consent + +### Interactive Cards + +- Forms, auth flows, and structured interactions within conversations + +### Conversation History + +- Persistent history with search, resume, feedback, and export + +### Developer Tools + +- Execution trace, session inspector, message inspector + +### Frontend Architecture + +- Composable routable extensions: `BoostChatPage`, `BoostAdminPage`, `BoostAgentStudioPage` +- Lazy loading via `React.lazy()` at extension boundaries — deployers who mount only chat never download admin code +- Capability-driven rendering adapting UI per provider's declared capabilities +- Config-driven feature flags via `app-config.yaml` and Backstage `featureFlagsApiRef` ## Impact -- `plugins/augment/src/plugin.ts` — new composable extensions -- `plugins/augment/src/components/ChatView.tsx` — lazy loading -- `plugins/augment/src/components/AugmentPage/AdminLayout.tsx` — lazy loading, capability checks -- `plugins/augment/src/config.d.ts` — feature flags schema +- `plugins/boost-frontend/src/plugin.ts` — composable routable extensions +- `plugins/boost-frontend/src/components/ChatView.tsx` — lazy loading, capability checks +- `plugins/boost-frontend/src/components/AdminLayout.tsx` — lazy loading per panel group +- `plugins/boost-common/src/config.d.ts` — feature flags schema diff --git a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/conversation-history/spec.md b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/conversation-history/spec.md index 2f8f4087e51..21936b8735b 100644 --- a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/conversation-history/spec.md +++ b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/conversation-history/spec.md @@ -35,7 +35,7 @@ Users can take actions on sessions and individual messages. #### Scenario: Provide feedback on a message - **WHEN** the user clicks thumbs up or thumbs down on an agent response -- **THEN** the feedback is stored via `augment_feedback` table with optional reasons +- **THEN** the feedback is stored via `boost_feedback` table with optional reasons - **AND** the feedback is associated with the specific message ID #### Scenario: Edit and regenerate @@ -53,7 +53,7 @@ Users can take actions on sessions and individual messages. - **WHEN** an admin toggles "Show all users" in the history panel - **THEN** sessions from all users are visible (not just the current user's) -- **AND** this is gated by `augment.admin` permission +- **AND** this is gated by `boost.admin` permission ### Requirement: Developer Inspection Tools diff --git a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/frontend-composability/spec.md b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/frontend-composability/spec.md index 7c88336d368..b25468c6e20 100644 --- a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/frontend-composability/spec.md +++ b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/frontend-composability/spec.md @@ -2,7 +2,7 @@ > **Status: Draft** — Pre-implementation specification. Subject to change during implementation. -The frontend must be decomposed from a monolithic `AugmentPage` into composable extensions with lazy loading, feature flags, and capability-driven rendering. +The frontend must be decomposed from a monolithic `BoostPage` into composable extensions with lazy loading, feature flags, and capability-driven rendering. ## ADDED Requirements @@ -13,20 +13,20 @@ Deployers can mount chat, admin, and agent studio independently. #### Scenario: Independent chat extension - **WHEN** a deployer wants only the chat interface without admin panels -- **THEN** they mount `AugmentChatPage` as a standalone routable extension -- **AND** it is provided via `augmentPlugin.provide(createRoutableExtension({ name: 'AugmentChatPage', mountPoint: chatRouteRef }))` +- **THEN** they mount `BoostChatPage` as a standalone routable extension +- **AND** it is provided via `boostPlugin.provide(createRoutableExtension({ name: 'BoostChatPage', mountPoint: chatRouteRef }))` - **AND** it can be configured independently in `dynamic-plugins.yaml` with its own `dynamicRoutes` entry #### Scenario: Independent admin extension - **WHEN** a deployer wants to mount the admin panel at a separate route -- **THEN** they mount `AugmentAdminPage` as a standalone routable extension +- **THEN** they mount `BoostAdminPage` as a standalone routable extension - **AND** it uses the existing `settingsAdminRouteRef` mount point #### Scenario: Monolithic default preserved - **WHEN** no specific extensions are configured -- **THEN** the existing `AugmentPage` continues to work as the all-in-one default +- **THEN** the default `BoostPage` continues to work as the all-in-one composition root - **AND** each extension is independently mountable ### Requirement: Lazy Loading in Primary Paths @@ -55,7 +55,7 @@ Deployers control feature visibility via `app-config.yaml`. - **WHEN** an administrator configures feature flags in `app-config.yaml` - **THEN** the following features can be individually enabled or disabled: ```yaml - augment: + boost: features: agentCreation: true devSpaces: false diff --git a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/tasks.md b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/tasks.md index c380a3abcbf..35e2c832de3 100644 --- a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/tasks.md +++ b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/tasks.md @@ -16,7 +16,7 @@ ## 3. Feature Flags (P1) -- [ ] 3.1 Add `augment.features` section to frontend `config.d.ts` schema +- [ ] 3.1 Add `boost.features` section to frontend `config.d.ts` schema - [ ] 3.2 Register feature flags with Backstage `featureFlagsApiRef` in `createPlugin` call - [ ] 3.3 Create `useFeatureFlags` hook that reads from `configApiRef` with `featureFlagsApiRef` overrides - [ ] 3.4 Gate `agentCreation`, `devSpaces`, `workflowBuilder`, `sandbox`, `observability`, `adminPanel` behind feature flags diff --git a/workspaces/boost/openspec/changes/platform-operations-deployment/design.md b/workspaces/boost/openspec/changes/platform-operations-deployment/design.md index ea647da1acc..972221fb904 100644 --- a/workspaces/boost/openspec/changes/platform-operations-deployment/design.md +++ b/workspaces/boost/openspec/changes/platform-operations-deployment/design.md @@ -2,7 +2,7 @@ ## Context -Boost implements the runtime configuration engine (DB-backed overlay, 25+ keys) with proper architecture from the start, informed by augment's experience. Augment built this as a product feature but accumulated debt: 671 lines of hand-written validators, no documentation of config field scopes, raw `Map<>` caches instead of Backstage `cacheService`, and a 1,500+ line config schema growing without resolution. Boost uses Zod schema-driven validation and `cacheService` from day one. +Boost implements the runtime configuration engine (DB-backed overlay, 25+ keys) with proper architecture from the start. Zod schema-driven validation and Backstage `cacheService` are used from day one — no hand-written validators, no raw `Map<>` caches. ## Goals @@ -14,30 +14,30 @@ Boost implements the runtime configuration engine (DB-backed overlay, 25+ keys) ## Non-Goals - Removing the DB-backed dynamic config system (it's a product feature) -- Migrating provider-specific caches (covered in platform-architecture change) -- Migrating catalog entity candidates (covered in agent-creation-discovery change) +- Provider-specific caches (covered in platform-architecture change) +- Catalog entity providers (covered in agent-creation-discovery change) ## Decisions -### Decision 1: Zod schemas derived from config.d.ts +### Decision 1: Zod schemas as single source of truth -Replace `configValidation.ts` with Zod schemas that are the single source of truth. The TypeScript `config.d.ts` interface is generated from the Zod schemas (not the other way around). This ensures DB-stored values are validated by the same rules as YAML values. +Zod schemas define all admin-configurable fields. The TypeScript `config.d.ts` interface is generated from the Zod schemas (not the other way around). This ensures DB-stored values are validated by the same rules as YAML values — a single validation path for all config sources. -### Decision 2: Cache migration order follows traffic and risk +### Decision 2: Cache inventory via cacheService -1. `RuntimeConfigResolver` (cache #1) — highest traffic, 30s TTL, cleanest migration -2. `ConversationRegistry` (cache #8) — add TTL (24h), multi-instance benefit -3. `DocumentSyncService` (cache #9) — multi-instance sync consistency -4. `KagentiProvider` session maps (cache #10) — multi-instance safety -5. `ClientManager` (cache #11) — low risk, singleton pattern -6. `ConfigResolutionService` (cache #14) — eliminate entirely (delegate to #1) -7. `conversationAgents` (cache #15) — new, session-scoped -8. `rateLimiter store` (cache #16) — new, per-window -9. `BackendApprovalStore.pending` (cache #17) — new, request-scoped HITL approvals +All operational caches use `cacheService` from the start. The cache inventory covers the same operational needs identified in the Augment analysis (17 cache use cases): -Caches #12 and #13 (toolscope) are migrated via the injectable `CacheAdapter` in the toolscope extraction (covered in agent-creation-discovery change). +1. `RuntimeConfigResolver` — highest traffic, 30s TTL, immediate invalidation on write +2. `ConversationRegistry` — 24h TTL, multi-instance benefit +3. `DocumentSyncService` — content hash tracking, multi-instance consistency +4. Provider session maps — session-appropriate TTL +5. `ClientManager` — identity-keyed, singleton pattern +6. Config resolution — single cache layer (delegates to RuntimeConfigResolver, no duplicate wrapper) +7. Conversation-agent maps — session-scoped +8. Rate limiter state — per-window +9. HITL approval pending state — request-scoped -**Note:** Config schema has grown to 1,500+ lines (was 1,393 at original audit). Hand-written validators are 671 lines. Each new feature (agent approval, skills marketplace, token exchange, DevSpaces credentials) adds config keys without Zod migration, increasing eventual cleanup cost. +Provider-specific caches (embedding, tool scope) live in their respective modules and also use `cacheService` (covered in platform-architecture change). ### Decision 3: Config field metadata annotation @@ -51,5 +51,5 @@ This metadata drives both the admin UI (which fields to show) and validation (wh ## Risks -- **Redis dependency in production:** `cacheService` defaults to in-memory but uses Redis when configured. Deployments without Redis lose multi-instance cache sharing. Mitigated: in-memory mode is functionally identical to current behavior. -- **Schema migration for existing DB values:** Switching to schema-driven validation may reject currently-stored values. Mitigated by running a one-time migration that validates and reports (but doesn't block) existing values. +- **Redis dependency in production:** `cacheService` defaults to in-memory but uses Redis when configured. Deployments without Redis lose multi-instance cache sharing. Mitigated: in-memory mode is functionally identical for single-instance deployments. +- **Schema evolution:** New config fields added over time must have Zod schemas defined alongside them. Mitigated by making Zod schema the required entry point for any new config field — no config key can be added without a schema definition. diff --git a/workspaces/boost/openspec/changes/platform-operations-deployment/proposal.md b/workspaces/boost/openspec/changes/platform-operations-deployment/proposal.md index 9e9e2f192fe..fbdd0b1f230 100644 --- a/workspaces/boost/openspec/changes/platform-operations-deployment/proposal.md +++ b/workspaces/boost/openspec/changes/platform-operations-deployment/proposal.md @@ -4,31 +4,71 @@ An AI platform requiring code changes or restarts for configuration changes is unusable in production. Administrators need to deploy cleanly, manage agents and orchestration, configure RAG pipelines, tune 25+ runtime parameters, and white-label the experience — all without touching source code. -The current runtime configuration engine uses a DB-backed dynamic overlay that is unique across all RHDH plugins and bypasses Backstage's config validation pipeline. The 14 home-grown caches used for operational state (config resolution, session management, content hashes) should migrate to Backstage's `cacheService` for multi-instance safety and Redis backing in production. +Boost builds its operations layer on Backstage-native services from day one, avoiding the custom infrastructure patterns that created tech debt in the Augment reference prototype. -## What Changes +## What Boost Builds -### Current Capabilities (retroactive documentation) +### Deployment -- RHDH dynamic plugin (OCI) and Backstage static plugin (npm) deployment -- Agent and orchestration management via admin panel -- RAG knowledge pipeline: document ingestion, vector stores, RAG playground -- Runtime configuration engine: YAML baseline + DB overrides, 25+ keys, 30s cache TTL -- White-label branding: name, logo, colors, welcome screen, featured agents -- Admin onboarding experience +Boost ships as a set of modular RHDH dynamic plugins (OCI) and Backstage static plugins (npm). Core plugin and provider modules are independently installable — deployers choose only what they need: -### Architectural Improvements (from tech debt analysis) +| Package | Purpose | +| --------------------------------- | ----------------------------------------------------------------- | +| `boost-frontend` | Chat UI, agent gallery, admin panels, composable extensions | +| `boost-common` | Shared types, permissions, service refs | +| `boost-backend` | Core routes, services, middleware, cross-cutting entity providers | +| `boost-backend-module-llamastack` | Llama Stack agentic provider | +| `boost-backend-module-kagenti` | Kagenti agentic provider | +| `llamastack-entity-provider` | Llama Stack catalog entities (independently deployable) | +| `kagenti-entity-provider` | Kagenti catalog entities (independently deployable) | -- Migrate `RuntimeConfigResolver` cache (cache #1) to Backstage `cacheService` -- Migrate `ConversationRegistry` (cache #8), `DocumentSyncService` content hashes (cache #9), and session maps (cache #10) to `cacheService` -- Migrate `ClientManager` (cache #11), `EmbeddingCache` (cache #12), `SessionCache` (cache #13), `ConfigResolutionService` (cache #14) to `cacheService` -- Replace hand-written config validators (`configValidation.ts`, 668 lines) with schema-driven validation -- Add config-driven feature flags for frontend -- Document YAML-only vs. DB-overridable config fields +### Runtime Configuration Engine + +Boost implements a DB-backed dynamic configuration overlay (YAML baseline + database overrides, 25+ keys) with these architectural choices: + +- **Zod schema-driven validation** — Zod schemas are the single source of truth for config validation. The TypeScript `config.d.ts` interface is generated from Zod schemas, ensuring DB-stored values are validated by the same rules as YAML values. No hand-written validators. +- **Config field scoping** — every field is annotated with a `configScope`: `yaml-only` (e.g., database connection, security mode), `db-overridable` (e.g., model name, system prompt), or `db-only` (e.g., prompt groups, branding). This metadata drives admin UI rendering and write validation. +- **Config-driven feature flags** — deployers control feature visibility (agent creation, DevSpaces, workflow builder, sandbox, observability, admin panel) via `app-config.yaml`, read through Backstage's `featureFlagsApiRef`. + +### Operational Caching via Backstage `cacheService` + +All operational caches use Backstage `cacheService` from day one — no raw `Map<>` caches. This provides Redis-backed caching in production, consistent TTL semantics, and multi-instance safety. Boost's cache inventory covers the same operational needs identified in the Augment analysis (17 cache use cases): + +- Config resolution (30s TTL) +- Conversation registry (24h TTL) +- Document sync content hashes +- Provider session maps +- Client manager singletons +- Conversation agent mappings (session-scoped) +- Rate limiter windows (per-window) +- HITL approval pending state (request-scoped) + +Provider-specific caches (embedding, tool scope) live in their respective provider modules and also use `cacheService`. + +### Agent & Orchestration Management + +Admin panel for managing agents and orchestration rules — agent lifecycle (Draft → Pending → Published → Archived), orchestration chain configuration, and provider settings. + +### RAG Knowledge Pipelines + +Document ingestion, vector store configuration, and RAG playground — enabling agents to ground answers in organizational knowledge. + +### White-Label Branding + +Runtime branding customization: name, logo, colors, welcome screen, and featured agents — all configurable via admin panel without redeployment. + +## Key Design Principles + +These principles are informed by the Augment reference prototype's experience (see `specifications/boost-context.md`): + +1. **Backstage-native services over custom infrastructure** — `cacheService`, `permissions`, `httpAuth`, `configApi` instead of bespoke equivalents +2. **Schema-driven validation over hand-written validators** — Zod as single source of truth eliminates the drift between config schemas and validation logic +3. **Modular plugin packaging from day one** — each provider is an independent `createBackendModule`, not a monolithic backend +4. **Config field documentation as code** — scope metadata lives with the schema, not in separate docs ## Impact -- `plugins/augment-backend/src/services/RuntimeConfigResolver.ts` — cacheService migration -- `plugins/augment-backend/src/services/configValidation.ts` — replace with schema-driven validation -- `plugins/augment-backend/src/providers/` — remaining cache migrations -- `plugins/augment/src/config.d.ts` — feature flags schema addition +- `plugins/boost-backend/src/services/` — RuntimeConfigResolver, config validation, cache management +- `plugins/boost-backend/src/routes/` — admin panel API routes +- `plugins/boost-common/src/config.d.ts` — generated from Zod schemas +- `plugins/boost-frontend/src/admin/` — admin panel components, feature flag integration diff --git a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/cache-migration/spec.md b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/cache-migration/spec.md index 125f3d39cb4..e3a53ff10c3 100644 --- a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/cache-migration/spec.md +++ b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/cache-migration/spec.md @@ -2,31 +2,23 @@ > **Status: Draft** — Pre-implementation specification. Subject to change during implementation. -All operational caches use Backstage `cacheService` from day one — no raw `Map<>` caches. This provides Redis-backed caching in production, consistent TTL semantics, and multi-instance safety. The cache inventory below is derived from augment's 17-cache analysis to ensure boost covers all the same operational caching needs with proper architecture. - -NOTE: Provider-specific caches (#2-#7) are covered in the platform-architecture change. Catalog entity candidate caches are covered in the agent-creation-discovery change. This spec covers the remaining operational caches (#1, #8-#14) plus 3 new caches identified in the May 26 analysis (#15-#17). - -**Full cache inventory (17 caches, 2 migrated, 15 remaining):** - -| # | Cache | Location | Status | Owner | -| --- | ---------------------------------- | ------------------------------ | --------------- | ---------------- | -| 1 | RuntimeConfigResolver | services/ | **This spec** | Platform ops | -| 2 | KagentiAgentCardCache | providers/kagenti/ | **Migrated ✓** | Platform arch | -| 3 | KagentiProvider.\_modelsCache | providers/kagenti/ | **Migrated ✓** | Platform arch | -| 4 | ResponsesApiProvider.\_modelsCache | providers/llamastack/ | Platform arch | Platform arch | -| 5 | McpAuthService tokens | providers/llamastack/auth/ | Platform arch | Platform arch | -| 6 | KeycloakTokenManager | providers/kagenti/client/ | Platform arch | Platform arch | -| 7 | BackendToolExecutor | providers/responses-api/tools/ | Platform arch | Platform arch | -| 8 | ConversationRegistry | providers/responses-api/ | **This spec** | Platform ops | -| 9 | DocumentSyncService | providers/responses-api/ | **This spec** | Platform ops | -| 10 | KagentiProvider session maps | providers/kagenti/ | **This spec** | Platform ops | -| 11 | ClientManager | providers/llamastack/ | **This spec** | Platform ops | -| 12 | EmbeddingCache (toolscope) | services/toolscope/ | Agent discovery | Via CacheAdapter | -| 13 | SessionCache (toolscope) | services/toolscope/ | Agent discovery | Via CacheAdapter | -| 14 | ConfigResolutionService | providers/llamastack/config/ | **This spec** | Platform ops | -| 15 | conversationAgents | OpenAIAgentsOrchestrator.ts | **This spec** | Platform ops | -| 16 | rateLimiter store | middleware/rateLimiter.ts | **This spec** | Platform ops | -| 17 | BackendApprovalStore.pending | responses-api/tools/ | **This spec** | Platform ops | +All operational caches use Backstage `cacheService` from day one — no raw `Map<>` caches. This provides Redis-backed caching in production, consistent TTL semantics, and multi-instance safety. The cache inventory below covers all operational caching needs identified from the Augment reference prototype analysis. + +NOTE: Provider-specific caches are covered in the platform-architecture change. Catalog entity caches are covered in the agent-creation-discovery change. This spec covers the core operational caches. + +**Cache inventory (boost operational caches):** + +| Cache Use Case | Module/Location | cacheService Configuration | +| ---------------------------------- | ----------------------- | ------------------------------------------------------------------- | +| RuntimeConfigResolver | core `boost-backend` | `cache.withOptions({ defaultTtl: '30s' })` + immediate invalidation | +| ConversationRegistry | core `boost-backend` | `cache.withOptions({ defaultTtl: '24h' })` | +| DocumentSyncService content hashes | core `boost-backend` | cache with no expiry (content hash tracking) | +| Provider session maps | each provider module | `cache.withOptions()` with session TTL | +| ClientManager | `llamastack` module | identity-keyed cache | +| Config resolution | core `boost-backend` | Delegates to RuntimeConfigResolver (single layer, no wrapper) | +| Conversation-agent maps | core `boost-backend` | session-scoped cache | +| Rate limiter state | core `boost-backend` | per-window cache | +| HITL approval pending state | `responses-api` toolkit | request-scoped cache | ## ADDED Requirements @@ -38,7 +30,7 @@ The highest-traffic cache uses Backstage cacheService. - **WHEN** `RuntimeConfigResolver` caches the merged effective config - **THEN** it uses `coreServices.cache` with `cache.set('effective-config', value, { ttl: '30s' })` -- **AND** immediate invalidation on write is preserved via `cache.delete('effective-config')` +- **AND** immediate invalidation on write is provided via `cache.delete('effective-config')` - **AND** in production with Redis, this cache is shared across multiple backend instances ### Requirement: Conversation and Session Caching @@ -47,14 +39,14 @@ Session correlation and conversation maps use cacheService. #### Scenario: ConversationRegistry uses cacheService -- **WHEN** `ConversationRegistry` maps response IDs to conversation IDs (currently cache #8, no TTL, max 10,000) -- **THEN** it uses `coreServices.cache` with a reasonable TTL (e.g., 24h for conversation mapping) -- **AND** max-size eviction is handled by the cache backend (no manual tracking) +- **WHEN** `ConversationRegistry` maps response IDs to conversation IDs +- **THEN** it uses `coreServices.cache` with a 24h TTL +- **AND** max-size eviction is handled by the cache backend -#### Scenario: Kagenti session maps use cacheService +#### Scenario: Provider session maps use cacheService -- **WHEN** `KagentiProvider` correlates sessions (currently cache #10, no TTL, max 10,000) -- **THEN** it uses `coreServices.cache` with a reasonable TTL +- **WHEN** a provider correlates sessions +- **THEN** it uses `coreServices.cache` with an appropriate session TTL - **AND** multi-instance safety is achieved via Redis backing ### Requirement: Document Sync Hash Caching @@ -63,22 +55,22 @@ Content hashes for change detection use cacheService. #### Scenario: DocumentSyncService uses cacheService -- **WHEN** `DocumentSyncService` tracks content hashes for change detection (currently cache #9, no TTL, max 10,000) +- **WHEN** `DocumentSyncService` tracks content hashes for change detection - **THEN** it uses `coreServices.cache` with no expiry (or very long TTL) - **AND** hashes are shared across instances for consistent sync behavior ### Requirement: Client and Config Service Caching -Singleton client instances and config wrappers use cacheService. +Singleton client instances and config services use cacheService. #### Scenario: ClientManager uses cacheService -- **WHEN** `ClientManager` caches HTTP client instances (currently cache #11, identity-based, max 1) +- **WHEN** `ClientManager` caches HTTP client instances - **THEN** it uses `coreServices.cache` for client instance caching - **AND** identity-based keying is preserved -#### Scenario: ConfigResolutionService delegates to RuntimeConfigResolver cache +#### Scenario: Config resolution uses a single cache layer -- **WHEN** `ConfigResolutionService` wraps RuntimeConfigResolver (currently cache #14) -- **THEN** it delegates entirely to the migrated RuntimeConfigResolver cache -- **AND** the duplicate wrapper cache is eliminated +- **WHEN** config resolution is needed +- **THEN** it delegates to `RuntimeConfigResolver` cache directly +- **AND** there is no duplicate wrapper cache — a single cache layer serves all config resolution diff --git a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/deployment/spec.md b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/deployment/spec.md index 20db10f7693..b1a0986b747 100644 --- a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/deployment/spec.md +++ b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/deployment/spec.md @@ -29,7 +29,7 @@ Deploy Augment as a traditional Backstage plugin with npm packages. #### Scenario: Static plugin installation -- **WHEN** the developer installs `@augment/plugin-augment`, `@augment/plugin-augment-backend`, and `@augment/plugin-augment-common` +- **WHEN** the developer installs `@boost/plugin-boost`, `@boost/plugin-boost-backend`, and `@boost/plugin-boost-common` - **THEN** frontend route, sidebar entry, icon, and backend plugin are registered manually - **AND** `app-config.yaml` is configured - **AND** the application is rebuilt and deployed diff --git a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/runtime-config/spec.md b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/runtime-config/spec.md index f01fa7ef935..26cd59c96b5 100644 --- a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/runtime-config/spec.md +++ b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/runtime-config/spec.md @@ -21,7 +21,7 @@ YAML baseline + database overrides with automatic fallback. #### Scenario: Config write invalidation - **WHEN** an admin writes a config value via the admin panel -- **THEN** `AdminConfigService` persists it to the `augment_admin_config` table +- **THEN** `AdminConfigService` persists it to the `boost_admin_config` table - **AND** the `RuntimeConfigResolver` cache is immediately invalidated - **AND** the new value takes effect within seconds (not waiting for TTL expiry) @@ -90,8 +90,8 @@ New features require additional runtime configuration fields. - **THEN** the following fields are available: | Field | Scope | Description | |---|---|---| - | `augment.agentApproval.mode` | db-overridable | Built-in or SonataFlow-managed approval | - | `augment.agentApproval.sonataflow.endpoint` | yaml-only | SonataFlow workflow endpoint | + | `boost.agentApproval.mode` | db-overridable | Built-in or SonataFlow-managed approval | + | `boost.agentApproval.sonataflow.endpoint` | yaml-only | SonataFlow workflow endpoint | #### Scenario: Skills marketplace configuration @@ -99,8 +99,8 @@ New features require additional runtime configuration fields. - **THEN** the following fields are available: | Field | Scope | Description | |---|---|---| - | `augment.skillsMarketplace.endpoint` | yaml-only | Skills catalog backend URL | - | `augment.skillsMarketplace.enabled` | db-overridable | Enable/disable skills marketplace | + | `boost.skillsMarketplace.endpoint` | yaml-only | Skills catalog backend URL | + | `boost.skillsMarketplace.enabled` | db-overridable | Enable/disable skills marketplace | #### Scenario: Token exchange configuration @@ -108,14 +108,14 @@ New features require additional runtime configuration fields. - **THEN** the following fields are available: | Field | Scope | Description | |---|---|---| - | `augment.kagenti.auth.tokenExchange.enabled` | yaml-only | Enable RFC 8693 token exchange | - | `augment.kagenti.auth.tokenExchange.audience` | yaml-only | Target audience for exchanged token | - | `augment.kagenti.auth.tokenExchange.userTokenHeader` | yaml-only | Header containing user OIDC token | + | `boost.kagenti.auth.tokenExchange.enabled` | yaml-only | Enable RFC 8693 token exchange | + | `boost.kagenti.auth.tokenExchange.audience` | yaml-only | Target audience for exchanged token | + | `boost.kagenti.auth.tokenExchange.userTokenHeader` | yaml-only | Header containing user OIDC token | #### Scenario: Credential encryption - **WHEN** sensitive credentials (DevSpaces tokens) are stored -- **THEN** they are encrypted at rest in the `augment_admin_config` table +- **THEN** they are encrypted at rest in the `boost_admin_config` table - **AND** the admin UI masks credential values ### Requirement: Config Schema Versioning @@ -125,7 +125,7 @@ DB-stored config values survive schema changes across upgrades. #### Scenario: Schema evolution on startup - **WHEN** boost starts and the Zod schema has changed since the last run -- **THEN** a startup migration validates all existing DB values against the current schema +- **THEN** a startup validation checks all existing DB values against the current schema - **AND** values that pass validation are kept as-is - **AND** values that fail validation are logged with details (field, stored value, validation error) - **AND** failed values are removed from the DB override, restoring the YAML baseline for those fields diff --git a/workspaces/boost/openspec/changes/platform-operations-deployment/tasks.md b/workspaces/boost/openspec/changes/platform-operations-deployment/tasks.md index c4ba78ccd05..ba559b7beac 100644 --- a/workspaces/boost/openspec/changes/platform-operations-deployment/tasks.md +++ b/workspaces/boost/openspec/changes/platform-operations-deployment/tasks.md @@ -20,11 +20,9 @@ - [ ] 2.3 Validate all config writes (YAML and DB) via Zod `.parse()` — no hand-written validators - [ ] 2.4 Annotate each field with `configScope`: `yaml-only`, `db-overridable`, or `db-only` - [ ] 2.5 Add Zod schemas for new config fields: agentApproval, skillsMarketplace, tokenExchange, DevSpaces credentials -- [ ] 2.6 Update admin UI to only show DB-overridable and DB-only fields -- [ ] 2.7 Create one-time migration script that validates existing DB values against new schemas -- [ ] 2.8 Implement credential encryption for sensitive DB-stored values (DevSpaces tokens) -- [ ] 2.9 Implement schema version tracking: store schema version alongside DB values, re-validate on startup -- [ ] 2.10 Implement startup migration: validate existing DB values against current Zod schema, remove invalid overrides with logging +- [ ] 2.6 Admin UI shows only DB-overridable and DB-only fields +- [ ] 2.7 Implement credential encryption for sensitive DB-stored values (DevSpaces tokens) +- [ ] 2.8 Implement schema version tracking: store schema version alongside DB values, re-validate on startup ## 3. Config Field Documentation (P2) @@ -35,6 +33,5 @@ - [ ] 4.1 Verify RuntimeConfigResolver cache works with both in-memory and Redis backends - [ ] 4.2 Verify config write → immediate invalidation → new value served in under 1 second -- [ ] 4.3 Verify Zod validation rejects the same invalid values that hand-written validators did -- [ ] 4.4 Verify existing DB values pass Zod validation (migration script) -- [ ] 4.5 Verify multi-instance cache sharing works with Redis in production config +- [ ] 4.3 Verify Zod validation rejects invalid config values +- [ ] 4.4 Verify multi-instance cache sharing works with Redis in production config diff --git a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/design.md b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/design.md index 7ce73d16f8e..1dd69a2f711 100644 --- a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/design.md +++ b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/design.md @@ -2,7 +2,7 @@ ## Context -Boost implements the provider abstraction as modular RHDH dynamic plugins from the start, informed by augment's experience. Augment had a clean provider abstraction design (`AgenticProvider` interface, extension point registration, hot-swap lifecycle) but locked everything inside one monolithic plugin with 17 raw `Map<>` caches, 18+ provider ID string checks, and 559 lines of Kagenti-specific types in the common package. Boost avoids all of these patterns by building modular, capability-gated, and cacheService-backed from day one. +Boost implements the provider abstraction as modular RHDH dynamic plugins from the start. The Augment reference prototype had a clean provider abstraction design (`AgenticProvider` interface, extension point registration, hot-swap lifecycle) but locked everything inside one monolithic plugin. Boost avoids this by building modular, capability-gated, and `cacheService`-backed from day one. ## Goals @@ -22,73 +22,69 @@ Boost implements the provider abstraction as modular RHDH dynamic plugins from t ## Decisions -### Decision 1: serviceRef lives in augment-common +### Decision 1: serviceRef lives in boost-common -The `augmentAiProviderServiceRef` is exported from `@augment/plugin-augment-common` alongside the `AgenticProvider` interface types. This allows both backend consumers and frontend type consumers to reference the interface from a single package without depending on the full backend. +The `boostAiProviderServiceRef` is exported from `boost-common` alongside the `AgenticProvider` interface types. This allows both backend consumers and frontend type consumers to reference the interface from a single package without depending on the full backend. ```typescript -// plugins/augment-common/src/services.ts +// plugins/boost-common/src/services.ts import { createServiceRef } from '@backstage/backend-plugin-api'; import type { AgenticProvider } from './types'; -export const augmentAiProviderServiceRef = createServiceRef({ - id: 'augment.ai-provider', +export const boostAiProviderServiceRef = createServiceRef({ + id: 'boost.ai-provider', scope: 'plugin', }); ``` -The core `augment-backend` plugin registers the default factory via `createServiceFactory` that resolves to the `ProviderManager`'s active provider. +The core `boost-backend` plugin registers the default factory via `createServiceFactory` that resolves to the `ProviderManager`'s active provider. ### Decision 2: Providers as backend modules, not separate plugins -Each provider is a `createBackendModule` (not `createBackendPlugin`), because providers extend the augment plugin — they don't stand alone. Module IDs: `llamastack`, `kagenti`. +Each provider is a `createBackendModule` (not `createBackendPlugin`), because providers extend the boost plugin — they don't stand alone. Module IDs: `llamastack`, `kagenti`. This follows the Backstage pattern established by `plugin-catalog-backend-module-*` and `plugin-kubernetes-backend-module-*`. -### Decision 3: cacheService replaces ALL provider-internal Map<> caches - -17 caches identified across the codebase; only 2 migrated to date. All providers must use `cacheService` consistently — no asymmetry between Kagenti (cacheService) and Llama Stack (raw Map). Provider modules depend on `coreServices.cache` and use `cache.withOptions()` for namespace isolation: - -| Current Cache | Location | Current State | Migration Target | -| ---------------------------------- | -------------------------------- | ------------------------ | ------------------------------------------------------------------- | -| RuntimeConfigResolver | `services/` | raw Map, 30s TTL | `cache.withOptions({ defaultTtl: '30s' })` + immediate invalidation | -| KagentiAgentCardCache | `providers/kagenti/` | **migrated ✓** | — | -| KagentiProvider.\_modelsCache | `providers/kagenti/` | **migrated ✓** | — | -| ResponsesApiProvider.\_modelsCache | `providers/llamastack/` | raw object | `cache.withOptions({ defaultTtl: '60s' })` — eliminate asymmetry | -| McpAuthService tokens | `providers/llamastack/auth/` | raw Map | `cache.set(key, token, { ttl: expiresIn })` | -| KeycloakTokenManager | `providers/kagenti/client/` | raw Map | `cache.set(key, token, { ttl: expiresIn })` | -| BackendToolExecutor | `providers/responses-api/tools/` | raw Map, unbounded | `cache.withOptions({ defaultTtl: '5m' })` | -| ConversationRegistry | `providers/responses-api/` | raw Map, no TTL, 10k max | `cache.withOptions({ defaultTtl: '24h' })` | -| DocumentSyncService | `providers/responses-api/` | raw Map, no TTL, 10k max | cache with no expiry (content hash tracking) | -| KagentiProvider session maps | `providers/kagenti/` | raw Map, no TTL, 10k max | `cache.withOptions()` with session TTL | -| ClientManager | `providers/llamastack/` | raw Map | identity-keyed cache | -| EmbeddingCache (toolscope) | `services/toolscope/` | raw Map, unbounded | Via injectable `CacheAdapter` | -| SessionCache (toolscope) | `services/toolscope/` | raw Map, 1h TTL, 1k max | Via injectable `CacheAdapter` | -| ConfigResolutionService | `providers/llamastack/config/` | wrapper | Delegates to migrated RuntimeConfigResolver | -| conversationAgents | `OpenAIAgentsOrchestrator.ts` | new raw Map | session-scoped cache | -| rateLimiter store | `middleware/rateLimiter.ts` | new raw Map | per-window cache | -| BackendApprovalStore.pending | `responses-api/tools/` | new raw Map | request-scoped cache | +### Decision 3: All caches use Backstage cacheService + +All provider caches use `cacheService` from day one — no raw `Map<>` caches. Provider modules depend on `coreServices.cache` and use `cache.withOptions()` for namespace isolation. The full cache inventory (informed by the 17 cache use cases identified in the Augment analysis): + +| Cache Use Case | Module/Location | cacheService Configuration | +| --------------------------- | ----------------------- | ------------------------------------------------------------------- | +| RuntimeConfigResolver | core `boost-backend` | `cache.withOptions({ defaultTtl: '30s' })` + immediate invalidation | +| Agent card data | `kagenti` module | `cache.withOptions({ defaultTtl: '5m' })` | +| Model lists (per provider) | each provider module | `cache.withOptions({ defaultTtl: '60s' })` | +| MCP auth tokens | `llamastack` module | `cache.set(key, token, { ttl: expiresIn })` | +| Keycloak tokens | `kagenti` module | `cache.set(key, token, { ttl: expiresIn })` | +| Tool schema cache | `responses-api` toolkit | `cache.withOptions({ defaultTtl: '5m' })` | +| Conversation registry | core `boost-backend` | `cache.withOptions({ defaultTtl: '24h' })` | +| Document sync hashes | core `boost-backend` | cache with no expiry (content hash tracking) | +| Provider session maps | each provider module | `cache.withOptions()` with session TTL | +| Client manager | `llamastack` module | identity-keyed cache | +| Embedding cache (toolscope) | `@boost/toolscope` | Via injectable `CacheAdapter` | +| Session cache (toolscope) | `@boost/toolscope` | Via injectable `CacheAdapter` | +| Config resolution | core `boost-backend` | Delegates to RuntimeConfigResolver cache (single layer) | +| Conversation-agent maps | core `boost-backend` | session-scoped cache | +| Rate limiter state | core `boost-backend` | per-window cache | +| HITL approval pending state | `responses-api` toolkit | request-scoped cache | Backstage's cache layer handles max-size eviction and Redis backing in production. ### Decision 4: Capability checks via ProviderCapabilities -Frontend replaces all `providerId === 'kagenti'` checks with capability queries. The `ProviderCapabilities` interface already exists and is partially used. The migration: +Frontend uses capability queries instead of provider identity checks: ```typescript -// Before (coupled to provider identity) -const isFullProvider = liveStatus?.providerId === 'kagenti'; - -// After (coupled to capabilities) +// Capability-based (what boost implements) const hasAgentCatalog = capabilities?.agentCatalog === true; const hasNamespaceScoping = capabilities?.namespaceScoping === true; ``` -### Decision 5: Kagenti-specific types extracted from augment-common +### Decision 5: Provider-specific types stay in their modules -Currently 559 lines (60+ interfaces) of Kagenti-only types are exported from `augment-common`, violating the type package boundary. These must be moved to the Kagenti provider module, with only the shared `AgenticProvider` interface and conversation types remaining in `augment-common`. +Provider-specific types (e.g., Kagenti-specific interfaces) live in their respective provider modules. Only shared interfaces (`AgenticProvider`, `ProviderDescriptor`, `ProviderCapabilities`, conversation types, `NormalizedStreamEvent`) live in `boost-common`. ## Risks - **Cache key collisions:** Mitigated by using `cache.withOptions()` which namespace-scopes keys per plugin/module. -- **Provider module interdependency:** Provider modules must not import from each other. Shared utilities live in `augment-common` or standalone packages. Boost enforces this from the start. +- **Provider module interdependency:** Provider modules must not import from each other. Shared utilities live in `boost-common` or standalone packages. Boost enforces this from the start. diff --git a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/proposal.md b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/proposal.md index d2834d4df7b..ab1a0ee4464 100644 --- a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/proposal.md +++ b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/proposal.md @@ -2,34 +2,52 @@ ## Why -Augment must be the experience layer above any AI platform, not a client of one. Enterprise customers run different AI backends — and they change their minds. The architecture must support pluggable providers, runtime hot-swap, normalized streaming, and multi-agent orchestration without vendor lock-in. +Boost must be the experience layer above any AI platform, not a client of one. Enterprise customers run different AI backends — and they change their minds. The architecture must support pluggable providers, runtime hot-swap, normalized streaming, and multi-agent orchestration without vendor lock-in. -The current implementation achieves the product goals but has critical architectural gaps that limit reusability and composability: no Backstage `serviceRef` for cross-plugin AI provider consumption, providers embedded inside one monolithic backend plugin rather than packaged as separate Backstage modules, and shared types scattered across provider-specific directories. +Boost builds this as modular RHDH dynamic plugins from the start: each provider is an independent Backstage backend module, the active provider is consumable cross-plugin via a Backstage `serviceRef`, and all caches use `cacheService`. Provider-specific types stay in their modules — only shared interfaces live in the common package. -## What Changes +## What Boost Builds -### Current Capabilities (retroactive documentation) +### Provider Abstraction -- Provider abstraction via `AgenticProvider` interface with required (`chat`, `chatStream`) and optional capabilities +- `AgenticProvider` interface with required (`chat`, `chatStream`) and optional capabilities - `ProviderDescriptor` declares ID, name, and capability matrix -- Backstage extension point (`augmentProviderExtensionPoint`) for provider registration -- Runtime hot-swap via `ProviderManager.switchProvider()` with rollback on failure -- Normalized streaming protocol (`NormalizedStreamEvent`) for frontend uniformity -- Two built-in providers: `ResponsesApiProvider` (Llama Stack) and `KagentiProvider` (Kagenti A2A) -- Frontend capability-based feature gating adapting UI per provider +- Backstage extension point (`boostProviderExtensionPoint`) for provider registration +- `boostAiProviderServiceRef` in `boost-common` for cross-plugin AI provider consumption -### Architectural Improvements (from tech debt analysis) +### Runtime Hot-Swap -- Create `augmentAiProviderServiceRef` so other plugins can consume the active AI provider -- Move `AgenticProvider` interface and conversation types to `augment-common` -- Package `ResponsesApiProvider` and `KagentiProvider` as separate Backstage backend modules -- Replace provider ID checks (`providerId === 'kagenti'`) with capability-based checks -- Extract `responses-api/` toolkit and `toolscope/` as standalone packages +- `ProviderManager.switchProvider()` with rollback on failure +- Live provider switching without downtime or data loss + +### Normalized Streaming + +- `NormalizedStreamEvent` union type covering all stream event categories +- Single event contract between all providers and the frontend + +### Provider Modules + +Two built-in provider modules, each as an independent `createBackendModule`: + +- `boost-backend-module-llamastack` — Llama Stack / Responses API provider +- `boost-backend-module-kagenti` — Kagenti A2A provider + +### Capability-Based Feature Gating + +- `ProviderCapabilities` interface drives frontend rendering — no provider ID string checks +- UI adapts per-provider based on declared capabilities (agent catalog, namespace scoping, DevSpaces, build pipelines) + +### Key Design Principles + +- **Providers as modules, not monoliths** — each provider is independently installable and removable +- **Capability checks over identity checks** — `capabilities.agentCatalog` instead of `providerId === 'kagenti'` +- **`cacheService` everywhere** — all provider caches use Backstage `cacheService` with namespace isolation via `cache.withOptions()` +- **Clean type boundaries** — provider-specific types stay in their modules; only shared interfaces in `boost-common` ## Impact -- `plugins/augment-common/` — new types and serviceRef -- `plugins/augment-backend/src/providers/` — provider extraction -- `plugins/augment-backend/src/plugin.ts` — serviceRef registration -- New packages: `plugin-augment-backend-module-llamastack`, `plugin-augment-backend-module-kagenti` -- `plugins/augment/src/` — replace provider ID checks with capability checks +- `plugins/boost-common/` — `AgenticProvider`, `NormalizedStreamEvent`, `boostAiProviderServiceRef` +- `plugins/boost-backend/src/plugin.ts` — serviceRef registration, ProviderManager +- `plugins/boost-backend-module-llamastack/` — Llama Stack provider module +- `plugins/boost-backend-module-kagenti/` — Kagenti provider module +- `plugins/boost-frontend/src/` — capability-based rendering throughout diff --git a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/multi-agent-orchestration/spec.md b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/multi-agent-orchestration/spec.md index cc9e5f04240..f71ba77cab6 100644 --- a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/multi-agent-orchestration/spec.md +++ b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/multi-agent-orchestration/spec.md @@ -46,13 +46,13 @@ Agents built in any framework are accessible via RHDH through the A2A protocol. - **THEN** agents are scoped to their namespace with backend-enforced allowlists - **AND** the namespace picker in the admin UI filters the agent catalog accordingly -### Requirement: ADK Orchestration Library +### Requirement: OpenAI Agent SDK Orchestration -The `@augment-adk/augment-adk` library handles agent continuity, turn counting, handoff logic, and tool execution. +The OpenAI Agent SDK (via Llama Stack Responses API) handles agent orchestration, handoff logic, and tool execution for the Llama Stack provider. -#### Scenario: ADK manages agent turn lifecycle +#### Scenario: Agent SDK manages multi-agent orchestration -- **WHEN** a chat interaction spans multiple agent turns -- **THEN** the ADK library tracks turn count against configured limits -- **AND** it manages handoff transitions between agents +- **WHEN** a chat interaction involves multi-agent handoffs +- **THEN** the OpenAI Agent SDK manages agent handoff transitions via the Responses API - **AND** it coordinates tool execution within agent turns +- **AND** orchestration is defined via YAML configuration (not custom code) diff --git a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-abstraction/spec.md b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-abstraction/spec.md index 2cd161152f0..90512c53c3a 100644 --- a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-abstraction/spec.md +++ b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-abstraction/spec.md @@ -12,7 +12,7 @@ The `AgenticProvider` interface defines the contract between Augment and any AI #### Scenario: Provider implements required capabilities -- **WHEN** a provider is registered with `augmentProviderExtensionPoint` +- **WHEN** a provider is registered with `boostProviderExtensionPoint` - **THEN** it must implement `chat()` and `chatStream()` methods - **AND** it must provide a `ProviderDescriptor` declaring its ID, name, and supported capabilities @@ -28,7 +28,7 @@ Providers register via a Backstage extension point, requiring zero Augment sourc #### Scenario: External provider module registers via extension point -- **WHEN** a Backstage backend module depends on `augmentProviderExtensionPoint` +- **WHEN** a Backstage backend module depends on `boostProviderExtensionPoint` - **THEN** it calls `addProvider()` to register its `AgenticProviderFactory` - **AND** the provider appears in the admin panel's provider switcher on next startup @@ -46,17 +46,17 @@ Other Backstage plugins must be able to consume the active AI provider via Backs #### Scenario: External plugin consumes active AI provider -- **WHEN** a Backstage plugin declares a dependency on `augmentAiProviderServiceRef` +- **WHEN** a Backstage plugin declares a dependency on `boostAiProviderServiceRef` - **THEN** it receives the currently active `AgenticProvider` instance - **AND** it can call `chat()`, `chatStream()`, and any declared optional capabilities - **AND** if the active provider is hot-swapped, the consuming plugin receives the new provider on next request -#### Scenario: Service ref declared in augment-common +#### Scenario: Service ref declared in boost-common -- **WHEN** the `augmentAiProviderServiceRef` is created via `createServiceRef` from `@backstage/backend-plugin-api` -- **THEN** it is exported from the `augment-common` package (not `augment-backend`) +- **WHEN** the `boostAiProviderServiceRef` is created via `createServiceRef` from `@backstage/backend-plugin-api` +- **THEN** it is exported from the `boost-common` package (not `boost-backend`) - **AND** its type parameter is the `AgenticProvider` interface -- **AND** its ID follows the pattern `augment.ai-provider` +- **AND** its ID follows the pattern `boost.ai-provider` ### Requirement: Shared Types in Common Package @@ -65,11 +65,11 @@ Provider interfaces and conversation types must live in the common package so bo #### Scenario: AgenticProvider types moved to common - **WHEN** the `AgenticProvider` interface, `ProviderDescriptor`, `ProviderCapabilities`, and `NormalizedStreamEvent` types are needed -- **THEN** they are imported from `@augment/plugin-augment-common` +- **THEN** they are imported from `@boost/plugin-boost-common` - **AND** provider-specific types (e.g., `LlamaStackConfig`, `KagentiConfig`) remain in their respective provider modules — not in the common package #### Scenario: Conversation types consolidated - **WHEN** conversation types (`ConversationSummary`, `ConversationDetails`, `InputItem`) are needed -- **THEN** they are imported from `@augment/plugin-augment-common` +- **THEN** they are imported from `@boost/plugin-boost-common` - **AND** they are no longer defined inside `providers/llamastack/conversationTypes.ts` diff --git a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-packaging/spec.md b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-packaging/spec.md index 611285630ce..035fd0eee47 100644 --- a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-packaging/spec.md +++ b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-packaging/spec.md @@ -12,9 +12,9 @@ The Llama Stack provider is packaged as an independent Backstage backend module #### Scenario: Module registration -- **WHEN** the `plugin-augment-backend-module-llamastack` package is installed -- **THEN** it creates a `createBackendModule` with `pluginId: 'augment'` and `moduleId: 'llamastack'` -- **AND** it registers `ResponsesApiProviderFactory` via `augmentProviderExtensionPoint` (AI capabilities — composable, accessed by the core backend) +- **WHEN** the `plugin-boost-backend-module-llamastack` package is installed +- **THEN** it creates a `createBackendModule` with `pluginId: 'boost'` and `moduleId: 'llamastack'` +- **AND** it registers `ResponsesApiProviderFactory` via `boostProviderExtensionPoint` (AI capabilities — composable, accessed by the core backend) - **AND** it composes `llamastack-entity-provider` internally, registering its entity providers via `catalogProcessingExtensionPoint` - **AND** `llamastack-entity-provider` is also independently deployable as its own RHDH dynamic plugin (without boost) - **AND** it depends on `coreServices.config` for Llama Stack connection settings @@ -26,10 +26,10 @@ The Llama Stack provider is packaged as an independent Backstage backend module - **THEN** it is packaged as an OCI image via `@red-hat-developer-hub/cli plugin export` - **AND** it is configured in `dynamic-plugins.yaml` as: ```yaml - - package: oci://registry/augment-backend-module-llamastack:tag!augment-backend-module-llamastack-dynamic + - package: oci://registry/boost-backend-module-llamastack:tag!boost-backend-module-llamastack-dynamic disabled: false ``` -- **AND** it can be installed or removed independently of the core augment backend +- **AND** it can be installed or removed independently of the core boost backend #### Scenario: Module uses Backstage cacheService @@ -44,9 +44,9 @@ The Kagenti provider is packaged as an independent Backstage backend module. #### Scenario: Module registration -- **WHEN** the `plugin-augment-backend-module-kagenti` package is installed -- **THEN** it creates a `createBackendModule` with `pluginId: 'augment'` and `moduleId: 'kagenti'` -- **AND** it registers `KagentiProviderFactory` via `augmentProviderExtensionPoint` (AI capabilities — composable, accessed by the core backend) +- **WHEN** the `plugin-boost-backend-module-kagenti` package is installed +- **THEN** it creates a `createBackendModule` with `pluginId: 'boost'` and `moduleId: 'kagenti'` +- **AND** it registers `KagentiProviderFactory` via `boostProviderExtensionPoint` (AI capabilities — composable, accessed by the core backend) - **AND** it composes `kagenti-entity-provider` internally, registering its entity providers via `catalogProcessingExtensionPoint` - **AND** `kagenti-entity-provider` is also independently deployable as its own RHDH dynamic plugin (without boost) - **AND** it depends on `coreServices.config` for Kagenti/Keycloak connection settings @@ -72,7 +72,7 @@ Provider-internal subsystems with zero Backstage coupling are extracted as stand #### Scenario: toolscope extracted as standalone package - **WHEN** the `services/toolscope/` subsystem (29 files, zero Backstage dependencies) is needed -- **THEN** it is available as `@augment/toolscope` (or `@augment-adk/toolscope`) +- **THEN** it is available as `@boost/toolscope` - **AND** the embedding cache (currently unbounded `Map<>`) is replaced with an injectable cache interface - **AND** the session cache (currently raw `Map<>` with 1h TTL, max 1000) uses the injected cache diff --git a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/tasks.md b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/tasks.md index c998a7285de..1403c57262a 100644 --- a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/tasks.md +++ b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/tasks.md @@ -2,63 +2,55 @@ ## 1. Types and Service Ref (P0) -- [ ] 1.1 Move `AgenticProvider`, `ProviderDescriptor`, `ProviderCapabilities` interfaces to `augment-common` -- [ ] 1.2 Move `NormalizedStreamEvent` union type to `augment-common` -- [ ] 1.3 Move `ConversationSummary`, `ConversationDetails`, `InputItem` from `providers/llamastack/conversationTypes.ts` to `augment-common` -- [ ] 1.4 Create `augmentAiProviderServiceRef` in `augment-common` via `createServiceRef` -- [ ] 1.5 Register default service factory in `augment-backend/plugin.ts` resolving to `ProviderManager.getActiveProvider()` -- [ ] 1.6 Verify no provider-specific types leak into common package - -## 2. Provider Module Extraction (P0) - -- [ ] 2.1 Create `plugin-augment-backend-module-llamastack` package with `createBackendModule({ pluginId: 'augment', moduleId: 'llamastack' })` -- [ ] 2.2 Move `ResponsesApiProvider`, `ResponsesApiProviderFactory`, and Llama Stack client code to the module -- [ ] 2.3 Create `plugin-augment-backend-module-kagenti` package with `createBackendModule({ pluginId: 'augment', moduleId: 'kagenti' })` -- [ ] 2.4 Move `KagentiProvider`, `KagentiProviderFactory`, and Kagenti client code to the module -- [ ] 2.5 Eliminate cross-provider import: remove `KagentiProvider.ts` import of `responses-api/chat/promptGeneration` +- [ ] 1.1 Define `AgenticProvider`, `ProviderDescriptor`, `ProviderCapabilities` interfaces in `boost-common` +- [ ] 1.2 Define `NormalizedStreamEvent` union type in `boost-common` +- [ ] 1.3 Define `ConversationSummary`, `ConversationDetails`, `InputItem` conversation types in `boost-common` +- [ ] 1.4 Create `boostAiProviderServiceRef` in `boost-common` via `createServiceRef` +- [ ] 1.5 Register default service factory in `boost-backend/plugin.ts` resolving to `ProviderManager.getActiveProvider()` +- [ ] 1.6 Verify no provider-specific types in common package — only shared interfaces + +## 2. Provider Module Packages (P0) + +- [ ] 2.1 Create `boost-backend-module-llamastack` package with `createBackendModule({ pluginId: 'boost', moduleId: 'llamastack' })` +- [ ] 2.2 Implement `ResponsesApiProvider` and `ResponsesApiProviderFactory` in the Llama Stack module +- [ ] 2.3 Create `boost-backend-module-kagenti` package with `createBackendModule({ pluginId: 'boost', moduleId: 'kagenti' })` +- [ ] 2.4 Implement `KagentiProvider` and `KagentiProviderFactory` in the Kagenti module +- [ ] 2.5 Ensure no cross-provider imports between modules - [ ] 2.6 Verify each provider module starts and registers independently via extension point -## 3. Cache Migration — Provider Caches (P1) +## 3. Provider Caches — cacheService from Day One (P1) -- [ ] 3.1 Add `coreServices.cache` dependency to provider modules -- [x] 3.2 KagentiProvider.\_modelsCache — already migrated to cacheService ✓ -- [x] 3.3 KagentiAgentCardCache — already migrated to cacheService ✓ -- [ ] 3.4 Replace `ResponsesApiProvider._modelsCache` (raw object) with `cache.withOptions({ defaultTtl: '60s' })` — eliminates model cache asymmetry -- [ ] 3.5 Replace `KeycloakTokenManager` (Map<>) with `cache.set(key, token, { ttl: expiresIn })` -- [ ] 3.6 Replace `McpAuthService` token caches (Map<>, dynamic TTL) with cacheService -- [ ] 3.7 Replace `BackendToolExecutor` schema cache (Map<>, unbounded) with `cache.withOptions({ defaultTtl: '5m' })` -- [ ] 3.8 Replace `ConversationRegistry` (Map<>, no TTL, 10k max) with `cache.withOptions({ defaultTtl: '24h' })` -- [ ] 3.9 Replace `KagentiProvider` session maps (Map<>, no TTL) with cacheService -- [ ] 3.10 Replace `ClientManager` (Map<>) with identity-keyed cacheService -- [ ] 3.11 Replace `DocumentSyncService` hash tracking (Map<>, no TTL) with cacheService (no expiry) +- [ ] 3.1 All provider modules depend on `coreServices.cache` +- [ ] 3.2 Implement model list cache in each provider via `cache.withOptions({ defaultTtl: '60s' })` +- [ ] 3.3 Implement agent card cache in Kagenti module via `cache.withOptions({ defaultTtl: '5m' })` +- [ ] 3.4 Implement Keycloak token cache in Kagenti module via `cache.set(key, token, { ttl: expiresIn })` +- [ ] 3.5 Implement MCP auth token cache in Llama Stack module via cacheService +- [ ] 3.6 Implement tool schema cache via `cache.withOptions({ defaultTtl: '5m' })` +- [ ] 3.7 Implement session maps in each provider via cacheService with session TTL +- [ ] 3.8 Implement client manager cache in Llama Stack module as identity-keyed cacheService -## 3b. Cache Migration — Core Caches (P0) +## 3b. Provider-Specific Types (P1) -- [ ] 3b.1 Replace `RuntimeConfigResolver` cache (raw Map, 30s TTL) with `coreServices.cache` + immediate invalidation via `cache.delete()` -- [ ] 3b.2 Verify `ConfigResolutionService` delegates correctly to migrated RuntimeConfigResolver - -## 3c. Kagenti Type Extraction (P1) - -- [ ] 3c.1 Move 559 lines of Kagenti-only types (60+ interfaces) from `augment-common` to the Kagenti provider module -- [ ] 3c.2 Keep only `AgenticProvider`, `ProviderDescriptor`, `ProviderCapabilities`, conversation types, and `NormalizedStreamEvent` in `augment-common` -- [ ] 3c.3 Verify common package contains only shared interfaces — no provider-specific types +- [ ] 3b.1 Define Kagenti-specific types (agent specs, tool configs, namespace models) in Kagenti module only +- [ ] 3b.2 Define Llama Stack-specific types in Llama Stack module only +- [ ] 3b.3 Verify common package contains only shared interfaces — no provider-specific types ## 4. Frontend Capability Checks (P1) -- [ ] 4.1 Replace `providerId === 'kagenti'` in `AdminLayout.tsx` with `ProviderCapabilities` query -- [ ] 4.2 Replace provider ID checks in `ChatView.tsx` with capability checks -- [ ] 4.3 Replace provider ID checks in `ChatHeader.tsx` with capability checks -- [ ] 4.4 Extend `ProviderCapabilities` interface with missing capability flags (agentCatalog, namespaceScoping, devSpaces, buildPipelines) +- [ ] 4.1 Implement `ProviderCapabilities`-based rendering in `AdminLayout.tsx` +- [ ] 4.2 Implement capability checks in `ChatView.tsx` +- [ ] 4.3 Implement capability checks in `ChatHeader.tsx` +- [ ] 4.4 Define `ProviderCapabilities` flags: agentCatalog, namespaceScoping, devSpaces, buildPipelines ## 5. Standalone Package Extraction (P2) -- [ ] 5.1 Extract `services/toolscope/` as `@augment/toolscope` with injectable cache interface -- [ ] 5.2 Extract shared `providers/responses-api/` utilities as `@augment/responses-api-toolkit` +- [ ] 5.1 Create `@boost/toolscope` package with injectable cache interface (`CacheAdapter`) +- [ ] 5.2 Create `@boost/responses-api-toolkit` for shared Responses API utilities ## 6. Dynamic Plugin Packaging (P2) -- [ ] 6.1 Configure `plugin-augment-backend-module-llamastack` for RHDH dynamic plugin export (OCI) -- [ ] 6.2 Configure `plugin-augment-backend-module-kagenti` for RHDH dynamic plugin export (OCI) +- [ ] 6.1 Configure `boost-backend-module-llamastack` for RHDH dynamic plugin export (OCI) +- [ ] 6.2 Configure `boost-backend-module-kagenti` for RHDH dynamic plugin export (OCI) - [ ] 6.3 Create `dynamic-plugins.yaml` examples for modular deployment ## 7. Verify @@ -66,4 +58,4 @@ - [ ] 7.1 Verify serviceRef consumption works from an external test plugin - [ ] 7.2 Verify hot-swap works with modular provider packages - [ ] 7.3 Verify cache behavior in both in-memory and Redis-backed modes -- [ ] 7.4 Verify no provider ID string checks remain in frontend +- [ ] 7.4 Verify no provider ID string checks in frontend — all capability-based diff --git a/workspaces/boost/openspec/changes/security-safety-governance/design.md b/workspaces/boost/openspec/changes/security-safety-governance/design.md index 091ff5e3a7f..88cd52b7696 100644 --- a/workspaces/boost/openspec/changes/security-safety-governance/design.md +++ b/workspaces/boost/openspec/changes/security-safety-governance/design.md @@ -2,18 +2,18 @@ ## Context -Boost builds the security and governance layer from scratch, informed by augment's experience. Augment's governance system grew into a parallel authorization layer (2,132 lines of custom code vs. 73 lines of Backstage permissions — 29x ratio) where 12 authorization decisions bypassed `permissions.authorize()`. Boost avoids this entirely: all authorization decisions use Backstage fine-grained permissions from day one. +Boost builds the security and governance layer with Backstage fine-grained permissions as the sole authorization mechanism from day one. The Augment reference prototype's governance system grew into a parallel authorization layer where authorization decisions bypassed `permissions.authorize()`. Boost avoids this entirely. -Augment also authenticated to Kagenti using a shared service-account token for all users, making per-user audit trails impossible. Boost implements RFC 8693 token exchange for per-user identity delegation from the start. +Boost also implements RFC 8693 token exchange for per-user identity delegation to Kagenti from the start, enabling per-user audit trails. ## Goals - Implement 16 fine-grained Backstage permissions as the sole authorization mechanism - Add conditional permission rules for ownership (IS_OWNER), separation of duties (IS_NOT_CREATOR), and lifecycle stage gating (HAS_LIFECYCLE_STAGE) - Implement RFC 8693 token exchange for per-user Kagenti identity -- Rename `none` security mode with deprecation path +- Use `development-only-no-auth` as the only dev security mode name (no legacy aliases) - Add CSRF protection and credential encryption -- Export all permissions from `augment-common` +- Export all permissions from `boost-common` ## Non-Goals @@ -26,7 +26,7 @@ Augment also authenticated to Kagenti using a shared service-account token for a ### Decision 1: 16 permissions with resource-based conditions and admin fallback -Agent and tool lifecycle actions get resource-based permissions with conditional rules. The `authorizeLifecycleAction` middleware replaces scattered per-route guards. On fine-grained DENY, the system falls back to checking `augment.admin` — enabling gradual adoption without breaking existing 2-permission deployments. +Agent and tool lifecycle actions use resource-based permissions with conditional rules. The `authorizeLifecycleAction` middleware is the single authorization entry point for all lifecycle routes. On fine-grained DENY, the system falls back to checking `boost.admin` — enabling deployments that prefer coarse-grained control to work without configuring all 16 permissions. ### Decision 2: Three conditional permission rules @@ -38,7 +38,7 @@ These rules are evaluated against loaded resources via `createConditionalDecisio ### Decision 3: Self-approval prevention stays layered -The `IS_NOT_CREATOR` permission rule is the primary enforcement mechanism. The existing route-level guard remains as defense-in-depth (belt and suspenders). Both layers are active in `security.mode === 'full'`. +The `IS_NOT_CREATOR` permission rule is the primary enforcement mechanism. A route-level guard remains as defense-in-depth (belt and suspenders). Both layers are active in `security.mode === 'full'`. ### Decision 4: Per-user token exchange is backend-only with graceful fallback @@ -54,6 +54,6 @@ Three non-overlapping authorization layers: ## Risks -- **RBAC policy complexity:** 16 permissions with conditions is more complex than 2. Mitigated by sensible defaults — `augment.access` as top-level gate and `augment.admin` available for coarse control. +- **RBAC policy complexity:** 16 permissions with conditions is more complex than 2. Mitigated by sensible defaults — `boost.access` as top-level gate and `boost.admin` available for coarse control. - **Token exchange reliability:** Keycloak availability becomes a dependency. Mitigated by graceful fallback to service-account token on any failure. - **SonataFlow trust boundary:** Callbacks bypass self-approval prevention via header. Callback identity verification should be implemented to close this gap. diff --git a/workspaces/boost/openspec/changes/security-safety-governance/proposal.md b/workspaces/boost/openspec/changes/security-safety-governance/proposal.md index 8a32d5858bb..f74d4b12c43 100644 --- a/workspaces/boost/openspec/changes/security-safety-governance/proposal.md +++ b/workspaces/boost/openspec/changes/security-safety-governance/proposal.md @@ -2,32 +2,47 @@ ## Why -Enterprise AI platforms must treat security, safety, and governance as foundational capabilities. Augment implements a three-tier security mode system, RBAC, content safety shields, SSRF protection, and zero data retention. However, the permission model is too coarse (2 permissions vs. peer plugins' 7+), the security modes are non-standard, and there are no resource-based permissions for owned resources. +Enterprise AI platforms must treat security, safety, and governance as foundational capabilities. Boost implements a three-tier security mode system, RBAC, content safety shields, SSRF protection, and zero data retention. The permission model uses 16 fine-grained Backstage permissions from day one, with resource-based permissions for owned resources and conditional rules for ownership and lifecycle gating. -## What Changes +## What Boost Builds -### Current Capabilities (retroactive documentation) +### Security Modes -- Three security modes: `none`, `plugin-only`, `full` -- RBAC via Keycloak OIDC + Backstage permissions (`augment.access`, `augment.admin`) -- Frontend `SecurityGate` with meaningful access-denied page -- Content safety shields (input/output) with fail-open/fail-closed -- SSRF protection via `SsrfGuard` on all backend HTTP paths -- Zero Data Retention mode with encrypted reasoning tokens +- Three security modes: `development-only-no-auth`, `plugin-only`, `full` +- Production environment detection with startup warning + +### Fine-Grained Permissions + +- 16 Backstage permissions across 3 resource types (`boost-agent`, `boost-tool`, plus functional permissions) +- Conditional rules: `IS_OWNER`, `IS_NOT_CREATOR`, `HAS_LIFECYCLE_STAGE` +- `authorizeLifecycleAction` middleware as the sole authorization path — no scattered per-route guards +- All authorization decisions use `permissions.authorize()` from day one + +### Identity & Authentication + +- RBAC via Keycloak OIDC + Backstage permissions (`boost.access`, `boost.admin` as top-level gates) +- RFC 8693 token exchange for per-user Kagenti identity delegation +- Graceful fallback to service-account token on any exchange failure - MCP 4-level auth chain - Kagenti SPIRE integration for infrastructure mTLS -- Provider offline detection and error boundaries -### Architectural Improvements (from tech debt analysis) +### Safety & Protection + +- Content safety shields (input/output) with fail-open/fail-closed modes +- SSRF protection via `SsrfGuard` on all backend HTTP paths +- Zero Data Retention mode with encrypted reasoning tokens +- CSRF protection via `X-Backstage-Request` header +- Credential encryption for sensitive DB-stored values + +### Frontend Security -- Expand from 2 to 7-9 fine-grained permissions (matching Lightspeed granularity) -- Add resource-based permissions for owned resources (sessions, documents, agents) -- Rename `none` security mode to `development-only-no-auth` with production warning -- Replace `adminUsers` fallback with standard Backstage RBAC-only pattern +- `SecurityGate` component with meaningful access-denied page +- `` wrapping for fine-grained UI gating +- Batched permission checks via `usePermissions` for performance ## Impact -- `plugins/augment-common/src/permissions.ts` — expanded permission definitions -- `plugins/augment-backend/src/middleware/security.ts` — fine-grained enforcement -- `plugins/augment/src/components/SecurityGate.tsx` — granular permission checks -- `plugins/augment-backend/src/routes/` — per-route permission requirements +- `plugins/boost-common/src/permissions.ts` — 16 permission definitions with resource types +- `plugins/boost-backend/src/middleware/security.ts` — `authorizeLifecycleAction` middleware +- `plugins/boost-frontend/src/components/SecurityGate.tsx` — granular permission checks +- `plugins/boost-backend/src/services/TokenExchangeManager.ts` — RFC 8693 implementation diff --git a/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md b/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md index 9d43323e901..1c2a400b57d 100644 --- a/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md +++ b/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md @@ -12,23 +12,23 @@ The plugin supports progressive security enforcement from development through pr #### Scenario: Security mode `none` (development only) -- **WHEN** `augment.security.mode` is set to `none` +- **WHEN** `boost.security.mode` is set to `none` - **THEN** the frontend shows no SecurityGate — all users pass as guest - **AND** the backend skips RBAC and treats everyone as admin - **AND** provider auth uses static token/TLS if configured #### Scenario: Security mode `plugin-only` (recommended production) -- **WHEN** `augment.security.mode` is set to `plugin-only` -- **THEN** `SecurityGate` wraps `AugmentPage` with `RequirePermission` -- **AND** the backend enforces `augment.access` via `requirePluginAccess` middleware +- **WHEN** `boost.security.mode` is set to `plugin-only` +- **THEN** `SecurityGate` wraps `BoostPage` with `RequirePermission` +- **AND** the backend enforces `boost.access` via `requirePluginAccess` middleware - **AND** admin access uses an explicit `adminUsers` allowlist - **AND** real user principal is extracted from the request #### Scenario: Security mode `full` (full production with token propagation) -- **WHEN** `augment.security.mode` is set to `full` -- **THEN** the backend enforces both `augment.access` and `augment.admin` via Backstage RBAC +- **WHEN** `boost.security.mode` is set to `full` +- **THEN** the backend enforces both `boost.access` and `boost.admin` via Backstage RBAC - **AND** MCP OAuth chain is configured for token propagation to tool servers - **AND** Kagenti uses Keycloak OAuth2 + SPIRE mTLS @@ -38,7 +38,7 @@ Unauthorized users see meaningful access-denied pages, not broken UIs. #### Scenario: SecurityGate blocks unauthorized access -- **WHEN** a user without `augment.access` permission navigates to Augment +- **WHEN** a user without `boost.access` permission navigates to Augment - **THEN** `SecurityGate` renders a meaningful access-denied page - **AND** the page explains what permission is needed and how to request access @@ -80,7 +80,7 @@ User identity is delegated to Kagenti via RFC 8693 OAuth2 Token Exchange so agen #### Scenario: Token exchange enabled -- **WHEN** `augment.kagenti.auth.tokenExchange.enabled` is `true` +- **WHEN** `boost.kagenti.auth.tokenExchange.enabled` is `true` - **AND** a user's OIDC token is available via the configured header (default: `X-Forwarded-Access-Token`) - **THEN** `TokenExchangeManager` exchanges the user's token for a Kagenti-scoped token via RFC 8693 - **AND** the exchanged token is cached per-user with TTL from token expiry @@ -100,9 +100,9 @@ User identity is delegated to Kagenti via RFC 8693 OAuth2 Token Exchange so agen - **THEN** the following config is used: | Key | Default | Description | |---|---|---| - | `augment.kagenti.auth.tokenExchange.enabled` | `false` | Enable per-user token exchange | - | `augment.kagenti.auth.tokenExchange.audience` | — | Target audience for exchanged token | - | `augment.kagenti.auth.tokenExchange.userTokenHeader` | `X-Forwarded-Access-Token` | Header containing user's OIDC token | + | `boost.kagenti.auth.tokenExchange.enabled` | `false` | Enable per-user token exchange | + | `boost.kagenti.auth.tokenExchange.audience` | — | Target audience for exchanged token | + | `boost.kagenti.auth.tokenExchange.userTokenHeader` | `X-Forwarded-Access-Token` | Header containing user's OIDC token | #### Scenario: LlamaStack provider unaffected @@ -127,7 +127,7 @@ Sensitive credentials are stored encrypted in the admin config database. #### Scenario: DevSpaces token encryption - **WHEN** a DevSpaces token is stored in admin configuration -- **THEN** the token is encrypted at rest in the `augment_admin_config` table +- **THEN** the token is encrypted at rest in the `boost_admin_config` table - **AND** plaintext storage of credentials is not permitted ## MODIFIED Requirements @@ -138,7 +138,7 @@ The `none` mode name must clearly indicate its development-only nature. #### Scenario: Renamed security mode with production warning -- **WHEN** `augment.security.mode` is set to `development-only-no-auth` (renamed from `none`) +- **WHEN** `boost.security.mode` is set to `development-only-no-auth` (renamed from `none`) - **THEN** behavior is identical to the current `none` mode - **AND** if detected in a non-development environment, a prominent warning is logged at startup - **AND** boost uses `development-only-no-auth` as the only name for this mode (no legacy aliases) 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 5295d016e00..fb08a537a2a 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 @@ -2,7 +2,7 @@ > **Status: Draft** — Pre-implementation specification. Subject to change during implementation. -Expand from 2 coarse permissions to 16 fine-grained permissions across 3 resource types with conditional rules, replacing custom route-level governance with proper Backstage RBAC. This eliminates the parallel authorization system (2,132 lines of custom governance code vs. 73 lines of Backstage permissions) by migrating all 12+ authorization decisions into `permissions.authorize()`. +Implement 16 fine-grained Backstage permissions across 3 resource types with conditional rules, using `permissions.authorize()` as the sole authorization mechanism. All authorization decisions go through Backstage RBAC from day one — no custom route-level governance layer. ## ADDED Requirements @@ -16,16 +16,16 @@ RBAC policies govern agent lifecycle transitions with ownership and separation-o - **THEN** the following agent permissions are registered: | Permission | Resource Type | Conditional Rules | Gates | |---|---|---|---| - | `augment.agent.list` | — | — | View agent list (visibility filtering) | - | `augment.agent.register` | — | — | Register an agent for governance | - | `augment.agent.promote` | `augment-agent` | `IS_OWNER`, `HAS_LIFECYCLE_STAGE` | Submit draft for review (draft→pending) | - | `augment.agent.approve` | `augment-agent` | `IS_NOT_CREATOR`, `HAS_LIFECYCLE_STAGE` | Approve pending (pending→published) | - | `augment.agent.demote` | `augment-agent` | — | Reject, request-unpublish, approve-unpublish | - | `augment.agent.publish` | `augment-agent` | — | Publish an approved agent | - | `augment.agent.unpublish` | `augment-agent` | `IS_OWNER` | Request unpublishing | - | `augment.agent.withdraw` | `augment-agent` | `IS_OWNER` | Withdraw pending submission | - | `augment.agent.delete` | `augment-agent` | `IS_OWNER`, `HAS_LIFECYCLE_STAGE` | Delete agent | - | `augment.agent.configure` | — | — | Edit agent configuration | + | `boost.agent.list` | — | — | View agent list (visibility filtering) | + | `boost.agent.register` | — | — | Register an agent for governance | + | `boost.agent.promote` | `boost-agent` | `IS_OWNER`, `HAS_LIFECYCLE_STAGE` | Submit draft for review (draft→pending) | + | `boost.agent.approve` | `boost-agent` | `IS_NOT_CREATOR`, `HAS_LIFECYCLE_STAGE` | Approve pending (pending→published) | + | `boost.agent.demote` | `boost-agent` | — | Reject, request-unpublish, approve-unpublish | + | `boost.agent.publish` | `boost-agent` | — | Publish an approved agent | + | `boost.agent.unpublish` | `boost-agent` | `IS_OWNER` | Request unpublishing | + | `boost.agent.withdraw` | `boost-agent` | `IS_OWNER` | Withdraw pending submission | + | `boost.agent.delete` | `boost-agent` | `IS_OWNER`, `HAS_LIFECYCLE_STAGE` | Delete agent | + | `boost.agent.configure` | — | — | Edit agent configuration | #### Scenario: Self-approval prevention via IS_NOT_CREATOR rule @@ -51,18 +51,18 @@ RBAC policies govern tool lifecycle transitions. - **THEN** the following tool permissions are registered: | Permission | Resource Type | Conditional Rules | Gates | |---|---|---|---| - | `augment.tool.promote` | `augment-tool` | `IS_OWNER` | Promote tool lifecycle | - | `augment.tool.approve` | `augment-tool` | `IS_NOT_CREATOR` | Approve tool promotion | - | `augment.tool.demote` | `augment-tool` | — | Demote tool lifecycle stage | - | `augment.tool.publish` | `augment-tool` | — | Publish a tool | - | `augment.tool.unpublish` | `augment-tool` | — | Unpublish a tool | + | `boost.tool.promote` | `boost-tool` | `IS_OWNER` | Promote tool lifecycle | + | `boost.tool.approve` | `boost-tool` | `IS_NOT_CREATOR` | Approve tool promotion | + | `boost.tool.demote` | `boost-tool` | — | Demote tool lifecycle stage | + | `boost.tool.publish` | `boost-tool` | — | Publish a tool | + | `boost.tool.unpublish` | `boost-tool` | — | Unpublish a tool | ### Requirement: Infrastructure Permissions #### Scenario: Kagenti admin permission - **WHEN** a user accesses Kagenti infrastructure operations -- **THEN** `augment.kagenti.admin` permission is checked +- **THEN** `boost.kagenti.admin` permission is checked - **AND** this covers namespace management, build pipelines, sandbox, and platform links ### Requirement: Conditional Permission Rules @@ -95,8 +95,8 @@ Existing 2-permission deployments continue to work without policy changes. - **WHEN** a lifecycle or admin action is invoked - **THEN** the specific fine-grained permission is checked via `permissions.authorize()` -- **AND** `augment.access` serves as a top-level gate (if denied, all sub-permissions are denied) -- **AND** `augment.admin` is available for deployments that prefer coarse-grained admin control +- **AND** `boost.access` serves as a top-level gate (if denied, all sub-permissions are denied) +- **AND** `boost.admin` is available for deployments that prefer coarse-grained admin control ### Requirement: Route-Level Authorization Middleware @@ -108,7 +108,7 @@ A shared middleware replaces scattered route-level guards. - **THEN** `authorizeLifecycleAction(permission, resourceLoader)` middleware: 1. Loads the resource (agent or tool) 2. Calls `permissions.authorize()` with the fine-grained permission and resource - 3. On DENY, falls back to `augment.admin` + 3. On DENY, falls back to `boost.admin` 4. On both DENY, returns 403 - **AND** this replaces the per-route `checkIsAdmin` + `getUserRef` + ownership patterns @@ -117,9 +117,9 @@ A shared middleware replaces scattered route-level guards. #### Scenario: Permissions exported from common package - **WHEN** permission constants are needed by frontend or backend -- **THEN** they are exported from `@augment/plugin-augment-common` +- **THEN** they are exported from `@boost/plugin-boost-common` - **AND** basic permissions use `createPermission` from `@backstage/plugin-permission-common` -- **AND** resource permissions use `createResourcePermission` with resource types `augment-agent` and `augment-tool` +- **AND** resource permissions use `createResourcePermission` with resource types `boost-agent` and `boost-tool` ### Requirement: Functional Area Permissions (non-lifecycle) @@ -129,9 +129,9 @@ A shared middleware replaces scattered route-level guards. - **THEN** the following functional permissions are also registered: | Permission | Action | Gates | |---|---|---| - | `augment.chat.read` | read | View chat interface, read messages | - | `augment.chat.create` | create | Send messages, start sessions | - | `augment.documents.manage` | update | Upload documents, sync RAG sources | - | `augment.mcp.manage` | update | Configure MCP servers | - | `augment.config.manage` | update | Modify admin configuration | + | `boost.chat.read` | read | View chat interface, read messages | + | `boost.chat.create` | create | Send messages, start sessions | + | `boost.documents.manage` | update | Upload documents, sync RAG sources | + | `boost.mcp.manage` | update | Configure MCP servers | + | `boost.config.manage` | update | Modify admin configuration | - **AND** these supplement the lifecycle permissions for comprehensive coverage diff --git a/workspaces/boost/openspec/changes/security-safety-governance/tasks.md b/workspaces/boost/openspec/changes/security-safety-governance/tasks.md index fadfcaface4..27ceee8ed61 100644 --- a/workspaces/boost/openspec/changes/security-safety-governance/tasks.md +++ b/workspaces/boost/openspec/changes/security-safety-governance/tasks.md @@ -1,67 +1,67 @@ # Tasks: Security, Safety & Governance -## 1. Permission Definitions (P0, additive) +## 1. Permission Definitions (P0) -- [ ] 1.1 Define 16 permissions in `augment-common/src/permissions.ts`: 10 agent, 5 tool, 1 kagenti-infra -- [ ] 1.2 Define resource types `augment-agent` and `augment-tool` using `createResourcePermission` +- [ ] 1.1 Define 16 permissions in `boost-common/src/permissions.ts`: 10 agent, 5 tool, 1 kagenti-infra +- [ ] 1.2 Define resource types `boost-agent` and `boost-tool` using `createResourcePermission` - [ ] 1.3 Define conditional rules: `IS_OWNER`, `IS_NOT_CREATOR`, `HAS_LIFECYCLE_STAGE` - [ ] 1.4 Define 5 functional permissions: `chat.read`, `chat.create`, `documents.manage`, `mcp.manage`, `config.manage` - [ ] 1.5 Register all permissions via `permissionsRegistry.addPermissions()` in backend `plugin.ts` -## 2. Authorization Middleware (P0, new files) +## 2. Authorization Middleware (P0) -- [ ] 2.1 Create `authorizeLifecycleAction(permission, resourceLoader)` middleware in `middleware/security.ts` +- [ ] 2.1 Create `authorizeLifecycleAction(permission, resourceLoader)` middleware in `boost-backend/src/middleware/security.ts` - [ ] 2.2 Implement fine-grained permission check via `permissions.authorize()` → DENY → 403 pattern - [ ] 2.3 Create resource loader functions for agents and tools (load from store, extract `createdBy` and `lifecycleStage`) -## 3. Route Refactoring — Agent Routes (P1) +## 3. Agent Routes — Permission Integration (P1) -- [ ] 3.1 Replace `GET /agents` visibility filtering with `augment.agent.list` + ownership condition -- [ ] 3.2 Replace `PUT /agents/:id/register` admin guard with `augment.agent.register` -- [ ] 3.3 Replace `PUT /agents/:id/promote` ownership+stage guards with `augment.agent.promote` (IS_OWNER + HAS_LIFECYCLE_STAGE) -- [ ] 3.4 Replace `PUT /agents/:id/promote` (pending→published) approval guard with `augment.agent.approve` (IS_NOT_CREATOR) -- [ ] 3.5 Replace `PUT /agents/:id/request-unpublish` with `augment.agent.unpublish` (IS_OWNER) -- [ ] 3.6 Replace `PUT /agents/:id/withdraw` with `augment.agent.withdraw` (IS_OWNER) -- [ ] 3.7 Replace `DELETE /agents/:id` stage+ownership guards with `augment.agent.delete` (IS_OWNER + HAS_LIFECYCLE_STAGE) +- [ ] 3.1 Implement `GET /agents` with `boost.agent.list` + ownership condition for visibility filtering +- [ ] 3.2 Implement `PUT /agents/:id/register` with `boost.agent.register` +- [ ] 3.3 Implement `PUT /agents/:id/promote` with `boost.agent.promote` (IS_OWNER + HAS_LIFECYCLE_STAGE) +- [ ] 3.4 Implement `PUT /agents/:id/promote` (pending→published) with `boost.agent.approve` (IS_NOT_CREATOR) +- [ ] 3.5 Implement `PUT /agents/:id/request-unpublish` with `boost.agent.unpublish` (IS_OWNER) +- [ ] 3.6 Implement `PUT /agents/:id/withdraw` with `boost.agent.withdraw` (IS_OWNER) +- [ ] 3.7 Implement `DELETE /agents/:id` with `boost.agent.delete` (IS_OWNER + HAS_LIFECYCLE_STAGE) -## 4. Route Refactoring — Tool Routes (P1) +## 4. Tool Routes — Permission Integration (P1) -- [ ] 4.1 Replace `PUT /tools/:id/promote` ownership guard with `augment.tool.promote` (IS_OWNER) -- [ ] 4.2 Replace `PUT /tools/:id/demote` admin guard with `augment.tool.demote` -- [ ] 4.3 Replace `PUT /tools/:id/publish` admin guard with `augment.tool.publish` -- [ ] 4.4 Replace `PUT /tools/:id/unpublish` admin guard with `augment.tool.unpublish` +- [ ] 4.1 Implement `PUT /tools/:id/promote` with `boost.tool.promote` (IS_OWNER) +- [ ] 4.2 Implement `PUT /tools/:id/demote` with `boost.tool.demote` +- [ ] 4.3 Implement `PUT /tools/:id/publish` with `boost.tool.publish` +- [ ] 4.4 Implement `PUT /tools/:id/unpublish` with `boost.tool.unpublish` -## 5. Route Refactoring — Kagenti Infra Routes (P1) +## 5. Kagenti Infra Routes — Permission Integration (P1) -- [ ] 5.1 Replace Kagenti admin route guards with `augment.kagenti.admin` +- [ ] 5.1 Implement Kagenti admin routes with `boost.kagenti.admin` ## 6. Frontend Permission Gating (P1) - [ ] 6.1 Wrap admin panel sections with `` using fine-grained permissions - [ ] 6.2 Batch permission checks via `usePermissions` (plural) for performance -- [ ] 6.3 Gate knowledge base panel with `augment.documents.manage` -- [ ] 6.4 Gate MCP panel with `augment.mcp.manage` -- [ ] 6.5 Gate config panel with `augment.config.manage` +- [ ] 6.3 Gate knowledge base panel with `boost.documents.manage` +- [ ] 6.4 Gate MCP panel with `boost.mcp.manage` +- [ ] 6.5 Gate config panel with `boost.config.manage` -## 7. Token Exchange (P1, new file + config) +## 7. Token Exchange (P1) - [ ] 7.1 Create `TokenExchangeManager` implementing RFC 8693 exchange - [ ] 7.2 Add per-user token caching with TTL from token expiry - [ ] 7.3 Add concurrent exchange deduplication - [ ] 7.4 Add graceful fallback to service-account token on all failures -- [ ] 7.5 Add config schema: `augment.kagenti.auth.tokenExchange.{enabled, audience, userTokenHeader}` +- [ ] 7.5 Add config schema: `boost.kagenti.auth.tokenExchange.{enabled, audience, userTokenHeader}` - [ ] 7.6 Integrate into `KagentiApiClient.requestCore()` — inject per-user token when available - [ ] 7.7 Extract user OIDC token from configurable request header in route handlers ## 8. CSRF and Credential Security (P2) - [ ] 8.1 Add `X-Backstage-Request` header to all frontend mutating fetch operations -- [ ] 8.2 Encrypt DevSpaces tokens in admin config DB (not plaintext) +- [ ] 8.2 Encrypt sensitive values in admin config DB (not plaintext) -## 9. Security Mode Rename (P3) +## 9. Security Mode Naming (P3) -- [ ] 9.1 Rename `none` to `development-only-no-auth` in config schema -- [ ] 9.2 Use `development-only-no-auth` as the only mode name (no legacy aliases) +- [ ] 9.1 Use `development-only-no-auth` as the dev security mode name from the start +- [ ] 9.2 No legacy aliases — `none` is not a valid mode name - [ ] 9.3 Add production environment detection heuristic with startup warning ## 10. Verify @@ -69,8 +69,8 @@ - [ ] 10.1 Verify fine-grained permission check → admin fallback → 403 pattern works - [ ] 10.2 Verify IS_OWNER blocks non-owner promote/delete/withdraw - [ ] 10.3 Verify IS_NOT_CREATOR blocks self-approval -- [ ] 10.4 Verify `augment.admin` works as coarse-grained alternative to fine-grained permissions +- [ ] 10.4 Verify `boost.admin` works as coarse-grained alternative to fine-grained permissions - [ ] 10.5 Verify token exchange fallback: disabled config → service-account token - [ ] 10.6 Verify token exchange fallback: Keycloak error → service-account token - [ ] 10.7 Verify token exchange fallback: missing header → service-account token -- [ ] 10.8 Verify `none` alias works with deprecation warning +- [ ] 10.8 Verify `none` is rejected with a clear error pointing to `development-only-no-auth` diff --git a/workspaces/boost/specifications/boost-context.md b/workspaces/boost/specifications/boost-context.md index 7b3d421c596..189398b30e6 100644 --- a/workspaces/boost/specifications/boost-context.md +++ b/workspaces/boost/specifications/boost-context.md @@ -32,7 +32,7 @@ All packages live at `rhdh-plugins/workspaces/boost/plugins/`: ``` workspace/boost/plugins/ ├── boost-frontend — Chat UI, agent gallery, admin panels, composable extensions -├── boost-common — Shared types, permissions, augmentAiProviderServiceRef +├── boost-common — Shared types, permissions, boostAiProviderServiceRef ├── boost-backend — Core routes, services, middleware, ProviderManager, cross-cutting entity providers ├── boost-backend-module-llamastack — Llama Stack agentic provider (composes llamastack-entity-provider) ├── boost-backend-module-kagenti — Kagenti agentic provider (composes kagenti-entity-provider) @@ -60,7 +60,7 @@ _Augment lesson: 2,132 lines of custom governance code implementing 12 authoriza ### 3. Providers as Independent RHDH Dynamic Plugins -Each AI platform provider is a separate `createBackendModule` packaged as an RHDH dynamic plugin. Provider types live in the common package. Cross-plugin consumption via `augmentAiProviderServiceRef`. +Each AI platform provider is a separate `createBackendModule` packaged as an RHDH dynamic plugin. Provider types live in the common package. Cross-plugin consumption via `boostAiProviderServiceRef`. _Augment lesson: Monolithic plugin with providers locked inside. No serviceRef for cross-plugin consumption. 559 lines of Kagenti-specific types polluting the common package. 13+ provider ID string checks coupling frontend to specific providers._ @@ -86,7 +86,7 @@ _Augment lesson: 671 lines of hand-written validators duplicating what schemas s The frontend is decomposed into composable routable extensions (`ChatPage`, `AdminPage`, `AgentStudioPage`) with `React.lazy()` at extension boundaries. Feature flags control visibility per deployment. -_Augment lesson: Single monolithic `AugmentPage` extension eagerly loading 200+ admin panel files. 13 components over 500 lines with zero lazy loading at primary entry points. No config-driven feature flags._ +_Augment lesson: Single monolithic `BoostPage` extension eagerly loading 200+ admin panel files. 13 components over 500 lines with zero lazy loading at primary entry points. No config-driven feature flags._ ### 8. UX/UXD-Driven UI Development diff --git a/workspaces/boost/specifications/prd/agent-creation-discovery.md b/workspaces/boost/specifications/prd/agent-creation-discovery.md index 4f35694b473..3cab5126f21 100644 --- a/workspaces/boost/specifications/prd/agent-creation-discovery.md +++ b/workspaces/boost/specifications/prd/agent-creation-discovery.md @@ -224,7 +224,7 @@ All methods produce an agent visible in the gallery and available in chat. **Integration architecture:** -- `GET /skills` proxies to the external skills catalog backend (endpoint configured via `augment.skillsMarketplace.endpoint`) +- `GET /skills` proxies to the external skills catalog backend (endpoint configured via `boost.skillsMarketplace.endpoint`) - `GET /skills/runtimes` and `GET /skills/domains` proxy filter metadata from the external catalog - Augment handles deployment only: K8s manifest generation, OCI init containers, namespace scoping - Deployed skills agents carry a `chatEndpoint` field for direct chat routing within Augment diff --git a/workspaces/boost/specifications/prd/ai-chat-interaction-experience.md b/workspaces/boost/specifications/prd/ai-chat-interaction-experience.md index 5a0361c5583..457b569eb0a 100644 --- a/workspaces/boost/specifications/prd/ai-chat-interaction-experience.md +++ b/workspaces/boost/specifications/prd/ai-chat-interaction-experience.md @@ -183,7 +183,7 @@ All frontend components and UI flows must align with RHDH usability and visual d The chat experience spans the full plugin stack: -**Frontend (`plugins/augment/src/`):** +**Frontend (`plugins/boost/src/`):** - `ChatContainer` orchestrates the chat experience (welcome vs thread mode) - `StreamingMessage` with `StreamingProgress` for real-time rendering @@ -202,7 +202,7 @@ Boost builds composable from the start, avoiding augment's monolithic frontend p - No component exceeds reasonable size without decomposition - All UI built from UX/UXD-provided mockups with PatternFly alignment -**Backend (`plugins/augment-backend/src/`):** +**Backend (`plugins/boost-backend/src/`):** - `chatRoutes.ts`: POST `/chat/stream`, POST `/chat/approve` - `sessionRoutes.ts`: GET `/sessions`, GET `/sessions/:id/messages` @@ -210,10 +210,10 @@ Boost builds composable from the start, avoiding augment's monolithic frontend p - `BackendApprovalStore` / `BackendApprovalHandler`: HITL continuation - Streaming pipeline: `createStreamEventForwarder` → provider → `NormalizedStreamEvent` → SSE -**Common (`plugins/augment-common/`):** +**Common (`plugins/boost-common/`):** - `NormalizedStreamEvent` union type covering all stream event categories -- Permission contracts: `augmentAccessPermission`, `augmentAdminPermission` +- Permission contracts: `boostAccessPermission`, `boostAdminPermission` --- diff --git a/workspaces/boost/specifications/prd/platform-operations-deployment.md b/workspaces/boost/specifications/prd/platform-operations-deployment.md index 3b19e1f3203..522783fe291 100644 --- a/workspaces/boost/specifications/prd/platform-operations-deployment.md +++ b/workspaces/boost/specifications/prd/platform-operations-deployment.md @@ -66,7 +66,7 @@ All packages live at `rhdh-plugins/workspaces/boost/plugins/`: | Package | Type | Description | | --------------------------------- | --------------- | --------------------------------------------------------------------------------------------------------- | | `boost-frontend` | Frontend plugin | Chat UI, agent gallery, admin panels, composable extensions | -| `boost-common` | Common library | Shared types (`AgenticProvider`, `NormalizedStreamEvent`, permissions), `augmentAiProviderServiceRef` | +| `boost-common` | Common library | Shared types (`AgenticProvider`, `NormalizedStreamEvent`, permissions), `boostAiProviderServiceRef` | | `boost-backend` | Backend plugin | Core routes, services, middleware, `ProviderManager`, cross-cutting entity providers (MCP, vector stores) | | `boost-backend-module-llamastack` | Backend module | Llama Stack agentic provider (composes `llamastack-entity-provider`) | | `boost-backend-module-kagenti` | Backend module | Kagenti agentic provider (composes `kagenti-entity-provider`) | @@ -226,7 +226,7 @@ app-config.yaml (YAML baseline) ↓ RuntimeConfigResolver (cacheService-backed, 30s TTL) ↓ (merges) -AdminConfigService (DB overrides, augment_admin_config table) +AdminConfigService (DB overrides, boost_admin_config table) ↓ Zod schema validation (single source of truth) ↓ @@ -238,10 +238,10 @@ Backend services + Frontend via admin API **Database layer:** - 6 tables in Backstage database (SQLite dev, PostgreSQL prod) -- `augment_admin_config`: runtime configuration overrides -- `augment_sessions`: conversation persistence -- `augment_messages`: message history -- `augment_feedback`: user feedback on messages +- `boost_admin_config`: runtime configuration overrides +- `boost_sessions`: conversation persistence +- `boost_messages`: message history +- `boost_feedback`: user feedback on messages **Deployment models:** diff --git a/workspaces/boost/specifications/prd/pluggable-ai-platform-architecture.md b/workspaces/boost/specifications/prd/pluggable-ai-platform-architecture.md index 3f347a11c38..02bcbd144bc 100644 --- a/workspaces/boost/specifications/prd/pluggable-ai-platform-architecture.md +++ b/workspaces/boost/specifications/prd/pluggable-ai-platform-architecture.md @@ -34,9 +34,9 @@ Hot-swaps between configured providers at runtime. Monitors capability differenc ### In Scope - Provider abstraction interface (`AgenticProvider`, `ProviderDescriptor`, `AgenticProviderFactory`) -- `augmentAiProviderServiceRef` for cross-plugin provider consumption +- `boostAiProviderServiceRef` for cross-plugin provider consumption - Backstage extension point for provider registration -- Provider types and interfaces in `augment-common` (not locked inside plugin) +- Provider types and interfaces in `boost-common` (not locked inside plugin) - Normalized streaming protocol (`NormalizedStreamEvent`) - Runtime provider hot-swap with rollback on failure - Capability-based frontend feature gating (replacing provider ID string checks) @@ -45,7 +45,7 @@ Hot-swaps between configured providers at runtime. Monitors capability differenc - Backstage `cacheService` for all operational caches (replacing home-grown `Map<>` caches) - Llama Stack multi-agent orchestration (config-driven agents, handoffs, agents-as-tools) - Kagenti provider (A2A protocol, K8s agent operations) -- ADK orchestration library (`@augment-adk/augment-adk`) +- OpenAI Agent SDK orchestration (via Llama Stack Responses API) - Future provider placeholders (Google ADK) ### Out of Scope @@ -68,7 +68,7 @@ Hot-swaps between configured providers at runtime. Monitors capability differenc - `AgenticProvider` interface: `chat()` and `chatStream()` are required capabilities; RAG, safety, evaluation, and conversation are optional capability objects - `ProviderDescriptor` declares the provider's ID, name, and supported capabilities - `AgenticProviderFactory` instantiates the provider from config -- Registration via `augmentProviderExtensionPoint` in a Backstage backend module +- Registration via `boostProviderExtensionPoint` in a Backstage backend module - No Augment source modification required **Built-in providers:** @@ -119,7 +119,7 @@ Hot-swaps between configured providers at runtime. Monitors capability differenc 1. Implement `AgenticProvider` interface (chat/chatStream required, optional capabilities) 2. Create `ProviderDescriptor` declaring ID, name, supported capabilities 3. Create `AgenticProviderFactory` that instantiates from config -4. Register via `augmentProviderExtensionPoint` in a Backstage backend module +4. Register via `boostProviderExtensionPoint` in a Backstage backend module 5. Deploy module alongside Augment backend 6. New provider appears in admin panel's provider switcher — zero Augment source changes @@ -158,7 +158,7 @@ Hot-swaps between configured providers at runtime. Monitors capability differenc - Agents-as-tools pattern: `call_{agent}` for manager-specialist delegation while keeping control - Per-agent config: model, temperature, max tokens, tool choice, MCP server subsets, vector store IDs -**ADK library:** `@augment-adk/augment-adk` handles agent continuity, turn counting, handoff logic, tool execution. +**Orchestration:** The OpenAI Agent SDK (via Llama Stack Responses API) handles agent orchestration, handoff logic, and tool execution. **Epics/Stories:** Epic 2 (Features 2.1) @@ -182,21 +182,21 @@ Hot-swaps between configured providers at runtime. Monitors capability differenc **How it works:** -- Each provider is a `createBackendModule` (not a standalone plugin) that registers via `augmentProviderExtensionPoint` +- Each provider is a `createBackendModule` (not a standalone plugin) that registers via `boostProviderExtensionPoint` - Provider modules have IDs: `llamastack` and `kagenti` - Both are exported as OCI images for RHDH dynamic plugin loading - Deployers install only the providers they need — no unused provider code loaded -- Provider modules depend on `augment-common` for shared types and `augmentAiProviderServiceRef` +- Provider modules depend on `boost-common` for shared types and `boostAiProviderServiceRef` - Boost ships modular from day one — no monolithic fallback needed **RHDH deployment example:** ```yaml # dynamic-plugins.override.yaml -- package: @augment/plugin-augment-backend-module-llamastack +- package: @boost/plugin-boost-backend-module-llamastack integrity: sha512-... disabled: false -- package: @augment/plugin-augment-backend-module-kagenti +- package: @boost/plugin-boost-backend-module-kagenti integrity: sha512-... disabled: false ``` @@ -238,14 +238,14 @@ Hot-swaps between configured providers at runtime. Monitors capability differenc **Provider capability system:** ``` -AgenticProvider (in augment-common) +AgenticProvider (in boost-common) ├── chat() / chatStream() — required ├── rag? — optional ├── safety? — optional ├── evaluation? — optional └── conversation? — optional -augmentAiProviderServiceRef (in augment-common) +boostAiProviderServiceRef (in boost-common) └── enables cross-plugin consumption of the active provider ProviderManager @@ -258,7 +258,7 @@ ProviderManager ``` boost-backend (core plugin) -├── augmentProviderExtensionPoint — provider registration interface +├── boostProviderExtensionPoint — provider registration interface ├── ProviderManager — lifecycle, swap, rollback ├── McpEntityProvider — MCP server catalog entities (cross-cutting) ├── VectorStoreEntityProvider — vector store catalog entities (cross-cutting) @@ -270,14 +270,14 @@ plugin-boost-backend-module-llamastack (RHDH dynamic plugin) ├── ResponsesApiProvider — Llama Stack AI capabilities ├── normalizeLlamaStackEvent() — stream normalizer ├── composes llamastack-entity-provider — catalog entities -├── registers via augmentProviderExtensionPoint +├── registers via boostProviderExtensionPoint └── registers via catalogProcessingExtensionPoint plugin-boost-backend-module-kagenti (RHDH dynamic plugin) ├── KagentiProvider — A2A protocol AI capabilities ├── KagentiStreamNormalizer — stream normalizer ├── composes kagenti-entity-provider — catalog entities -├── registers via augmentProviderExtensionPoint +├── registers via boostProviderExtensionPoint └── registers via catalogProcessingExtensionPoint llamastack-entity-provider (independently deployable RHDH dynamic plugin) diff --git a/workspaces/boost/specifications/prd/security-safety-governance.md b/workspaces/boost/specifications/prd/security-safety-governance.md index dfd704818a8..ecdb7d9db06 100644 --- a/workspaces/boost/specifications/prd/security-safety-governance.md +++ b/workspaces/boost/specifications/prd/security-safety-governance.md @@ -81,31 +81,31 @@ Security and governance UI surfaces (access-denied pages, approval queues, revie | Mode | Frontend | Backend | Provider Auth | Use Case | | -------------------------- | --------------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- | ---------------------------------------- | | `development-only-no-auth` | No gate — all users pass as guest | No RBAC, everyone is admin | Static token/TLS (if configured) | Development/demo only | -| `plugin-only` | SecurityGate wraps AugmentPage | user-cookie, augment.access, admin allow-list, real user principal | Token/TLS to Llama Stack, Keycloak OAuth2 for Kagenti | Recommended for production | -| `full` | SecurityGate wraps AugmentPage | Fine-grained RBAC (16 permissions), real user principal, mcpOAuth config | Token/TLS + MCP OAuth chain, Keycloak OAuth2 + per-user token exchange + SPIRE mTLS | Full production with identity delegation | +| `plugin-only` | SecurityGate wraps BoostPage | user-cookie, boost.access, admin allow-list, real user principal | Token/TLS to Llama Stack, Keycloak OAuth2 for Kagenti | Recommended for production | +| `full` | SecurityGate wraps BoostPage | Fine-grained RBAC (16 permissions), real user principal, mcpOAuth config | Token/TLS + MCP OAuth chain, Keycloak OAuth2 + per-user token exchange + SPIRE mTLS | Full production with identity delegation | **Note:** The legacy mode name `none` is deprecated; deployments should use `development-only-no-auth`. A prominent warning is logged if this mode is detected in a non-development environment. **Fine-grained RBAC (16 permissions across 3 resource types):** -| Permission | Resource Type | Conditional Rules | Description | -| ------------------------- | --------------- | --------------------------------------- | --------------------------------------------------- | -| `augment.agent.list` | — | — | View agent list (visibility filtering by ownership) | -| `augment.agent.register` | — | — | Register a new agent for governance | -| `augment.agent.promote` | `augment-agent` | `IS_OWNER`, `HAS_LIFECYCLE_STAGE` | Submit draft agent for review (draft→pending) | -| `augment.agent.approve` | `augment-agent` | `IS_NOT_CREATOR`, `HAS_LIFECYCLE_STAGE` | Approve pending agent (pending→published) | -| `augment.agent.demote` | `augment-agent` | — | Reject, request-unpublish, approve-unpublish | -| `augment.agent.publish` | `augment-agent` | — | Publish an approved agent | -| `augment.agent.unpublish` | `augment-agent` | `IS_OWNER` | Request unpublishing of a published agent | -| `augment.agent.withdraw` | `augment-agent` | `IS_OWNER` | Withdraw a pending submission | -| `augment.agent.delete` | `augment-agent` | `IS_OWNER`, `HAS_LIFECYCLE_STAGE` | Delete agent (draft stage only for non-admins) | -| `augment.agent.configure` | — | — | Edit agent configuration | -| `augment.tool.promote` | `augment-tool` | `IS_OWNER` | Promote tool through lifecycle | -| `augment.tool.approve` | `augment-tool` | `IS_NOT_CREATOR` | Approve tool promotion | -| `augment.tool.demote` | `augment-tool` | — | Demote tool lifecycle stage | -| `augment.tool.publish` | `augment-tool` | — | Publish a tool | -| `augment.tool.unpublish` | `augment-tool` | — | Unpublish a tool | -| `augment.kagenti.admin` | — | — | Kagenti infrastructure operations | +| Permission | Resource Type | Conditional Rules | Description | +| ----------------------- | ------------- | --------------------------------------- | --------------------------------------------------- | +| `boost.agent.list` | — | — | View agent list (visibility filtering by ownership) | +| `boost.agent.register` | — | — | Register a new agent for governance | +| `boost.agent.promote` | `boost-agent` | `IS_OWNER`, `HAS_LIFECYCLE_STAGE` | Submit draft agent for review (draft→pending) | +| `boost.agent.approve` | `boost-agent` | `IS_NOT_CREATOR`, `HAS_LIFECYCLE_STAGE` | Approve pending agent (pending→published) | +| `boost.agent.demote` | `boost-agent` | — | Reject, request-unpublish, approve-unpublish | +| `boost.agent.publish` | `boost-agent` | — | Publish an approved agent | +| `boost.agent.unpublish` | `boost-agent` | `IS_OWNER` | Request unpublishing of a published agent | +| `boost.agent.withdraw` | `boost-agent` | `IS_OWNER` | Withdraw a pending submission | +| `boost.agent.delete` | `boost-agent` | `IS_OWNER`, `HAS_LIFECYCLE_STAGE` | Delete agent (draft stage only for non-admins) | +| `boost.agent.configure` | — | — | Edit agent configuration | +| `boost.tool.promote` | `boost-tool` | `IS_OWNER` | Promote tool through lifecycle | +| `boost.tool.approve` | `boost-tool` | `IS_NOT_CREATOR` | Approve tool promotion | +| `boost.tool.demote` | `boost-tool` | — | Demote tool lifecycle stage | +| `boost.tool.publish` | `boost-tool` | — | Publish a tool | +| `boost.tool.unpublish` | `boost-tool` | — | Unpublish a tool | +| `boost.kagenti.admin` | — | — | Kagenti infrastructure operations | **Conditional permission rules:** @@ -116,9 +116,9 @@ Security and governance UI surfaces (access-denied pages, approval queues, revie **RBAC configuration:** - Fine-grained permissions are the primary authorization mechanism from day one -- `augment.access` serves as a top-level gate (if denied, all sub-permissions are denied) -- `augment.admin` is available for deployments that prefer coarse-grained admin control -- `augment.security.adminUsers` config is available for bootstrap/development only +- `boost.access` serves as a top-level gate (if denied, all sub-permissions are denied) +- `boost.admin` is available for deployments that prefer coarse-grained admin control +- `boost.security.adminUsers` config is available for bootstrap/development only **MCP auth chain (4 levels):** @@ -137,7 +137,7 @@ Security and governance UI surfaces (access-denied pages, approval queues, revie **Frontend enforcement:** -- `SecurityGate` wraps `AugmentPage` with loading, config errors, and `RequirePermission` +- `SecurityGate` wraps `BoostPage` with loading, config errors, and `RequirePermission` - Fine-grained permission checks via `usePermissions` (batched) per admin panel section - Unauthorized users see a meaningful access-denied page @@ -205,7 +205,7 @@ Draft → Pending → Published → Archived - Backend-only implementation: OIDC token read from a configurable request header (default: `X-Forwarded-Access-Token`) - `TokenExchangeManager` service: implements RFC 8693 exchange against Keycloak, with per-user token caching, concurrent request deduplication, and streaming-compatible token lifecycle - Graceful fallback on all failures: token exchange failure, missing header, disabled config, or Keycloak error → silently falls back to shared service-account token (no request blocking) -- Configuration: `augment.kagenti.auth.tokenExchange.enabled` (default: false), `audience`, `userTokenHeader` +- Configuration: `boost.kagenti.auth.tokenExchange.enabled` (default: false), `audience`, `userTokenHeader` - `ResponsesApiProvider` (Llama Stack) is unaffected: `setUserContext` method is optional and not implemented **Separation of authorization concerns:** @@ -266,13 +266,13 @@ Draft → Pending → Published → Archived ``` Frontend Layer -├── SecurityGate.tsx — wraps AugmentPage, checks RequirePermission +├── SecurityGate.tsx — wraps BoostPage, checks RequirePermission ├── usePermissions (batched) — fine-grained per admin panel section └── CSRF — X-Backstage-Request header on all mutating fetches Backend Middleware (5 layers) ├── Backstage HTTP — user-cookie / unauthenticated -├── requirePluginAccess — augment.access / skipped +├── requirePluginAccess — boost.access / skipped ├── authorizeLifecycleAction — fine-grained permission check via permissions.authorize() ├── User identity — real user principal (OIDC) / user-default/guest └── MCP OAuth — mcpOAuth config / N/A / N/A From 1b7c538c69276dcd41adc272c71d0e284611d191 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 4 Jun 2026 11:27:24 -0400 Subject: [PATCH 2/8] docs(boost): fix AugmentPage historical reference in boost-context.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert BoostPage back to AugmentPage in the "Augment lesson" for Design Principle #7, since this describes what the Augment reference prototype did wrong — not boost's design. Addresses fullsend review comment on PR #3292. The other 4 review findings (security-safety-governance permissions table, pluggable-ai-platform-architecture In Scope section, and platform-operations-deployment DB table names) were already fixed in the prior commit but the reviewer was comparing against the base branch diff rather than the final file state. Signed-off-by: gabemontero Co-Authored-By: Claude Opus 4.6 --- workspaces/boost/specifications/boost-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspaces/boost/specifications/boost-context.md b/workspaces/boost/specifications/boost-context.md index 189398b30e6..fb1711199e0 100644 --- a/workspaces/boost/specifications/boost-context.md +++ b/workspaces/boost/specifications/boost-context.md @@ -86,7 +86,7 @@ _Augment lesson: 671 lines of hand-written validators duplicating what schemas s The frontend is decomposed into composable routable extensions (`ChatPage`, `AdminPage`, `AgentStudioPage`) with `React.lazy()` at extension boundaries. Feature flags control visibility per deployment. -_Augment lesson: Single monolithic `BoostPage` extension eagerly loading 200+ admin panel files. 13 components over 500 lines with zero lazy loading at primary entry points. No config-driven feature flags._ +_Augment lesson: Single monolithic `AugmentPage` extension eagerly loading 200+ admin panel files. 13 components over 500 lines with zero lazy loading at primary entry points. No config-driven feature flags._ ### 8. UX/UXD-Driven UI Development From f7c700e922e6e5d58045537dd6c4ea64b41c591e Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 4 Jun 2026 13:14:54 -0400 Subject: [PATCH 3/8] claude's idea for an AGENTS.md file after perusing the fullsend repo Co-Authored-By: Claude Opus 4.6 Signed-off-by: gabemontero --- workspaces/boost/AGENTS.md | 110 +++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 workspaces/boost/AGENTS.md diff --git a/workspaces/boost/AGENTS.md b/workspaces/boost/AGENTS.md new file mode 100644 index 00000000000..3c5221e85a5 --- /dev/null +++ b/workspaces/boost/AGENTS.md @@ -0,0 +1,110 @@ +# AGENTS.md + +## Project overview + +Boost is a clean-room reimplementation of the Augment agentic developer portal for Red Hat Developer Hub (RHDH). It is a Backstage plugin workspace — not a fork of Augment. The project context, design principles, and relationship to Augment are documented in `specifications/boost-context.md`. Read that file before making any implementation decisions. + +## Specification-driven development + +This workspace uses a specification-first approach. Before writing code, read the relevant specifications: + +``` +workspaces/boost/ +├── specifications/ # Product requirements +│ ├── boost-context.md # Project rationale, 12 design principles, upstream monitoring +│ └── prd/ # Product Requirements Documents (one per capability area) +│ ├── use-case-index.md # All 25 use cases at a glance +│ ├── ai-chat-interaction-experience.md +│ ├── agent-creation-discovery.md +│ ├── pluggable-ai-platform-architecture.md +│ ├── platform-operations-deployment.md +│ └── security-safety-governance.md +├── openspec/ # Implementation specifications +│ └── changes/ # One directory per capability area: +│ ├── ai-chat-interaction-experience/ +│ ├── agent-creation-discovery/ +│ ├── pluggable-ai-platform-architecture/ +│ ├── platform-operations-deployment/ +│ └── security-safety-governance/ +│ ├── proposal.md # What and why +│ ├── design.md # Architecture decisions +│ ├── tasks.md # Implementation task breakdown +│ └── specs/ # Behavioral specs (Given/When/Then) +└── plugins/ # Plugin packages (implementation target) +``` + +When implementing an issue: + +1. Read `specifications/boost-context.md` for design principles — these are non-negotiable +2. Find the relevant PRD in `specifications/prd/` for product requirements +3. Find the matching change in `openspec/changes/` for design decisions, task breakdown, and behavioral specs +4. The `specs/` subdirectories contain acceptance criteria as scenarios — implementation must satisfy these + +## Architecture rules + +### Backstage-native services only + +Use Backstage `cacheService`, `permissions`, `httpAuth`, `configApi`, and `catalogApi`. Never build custom equivalents. All caches use `coreServices.cache` — no raw `Map<>` caches. + +### Provider isolation + +Each AI provider (`boost-backend-module-llamastack`, `boost-backend-module-kagenti`) is a separate `createBackendModule`. Providers must not import from each other. Shared types live in `boost-common`. + +### Capability checks, not identity checks + +Frontend rendering decisions use `ProviderCapabilities` interface checks. Never use `providerId === 'string'` comparisons. + +### Permissions as sole authorization + +All authorization decisions use `permissions.authorize()` with fine-grained permissions (`boost.agent.*`, `boost.tool.*`, `boost.kagenti.admin`). No custom route-level authorization logic. + +### Schema-driven validation + +Config validation uses Zod schemas as single source of truth. TypeScript types are generated from Zod. No hand-written validators. + +### Catalog entities for domain objects + +Agents, tools, models, MCP servers, and vector stores are Backstage catalog entities — not in-memory caches. Entity providers emit standard catalog entities. + +## Code conventions + +### Package structure + +| Package | Purpose | +| --------------------------------- | -------------------------------------------------------------------- | +| `boost-frontend` | Chat UI, agent gallery, admin panels, composable routable extensions | +| `boost-common` | Shared types, permissions, `boostAiProviderServiceRef` | +| `boost-backend` | Core routes, services, middleware, ProviderManager | +| `boost-backend-module-llamastack` | Llama Stack provider module | +| `boost-backend-module-kagenti` | Kagenti provider module | +| `llamastack-entity-provider` | Independently deployable catalog entity provider | +| `kagenti-entity-provider` | Independently deployable catalog entity provider | + +### Naming + +- Config namespace: `boost.*` (e.g., `boost.features.agentCreation`, `boost.security.mode`) +- Permission names: `boost.agent.*`, `boost.tool.*`, `boost.kagenti.admin`, `boost.access`, `boost.admin` +- Resource types: `boost-agent`, `boost-tool` +- DB tables: `boost_admin_config`, `boost_sessions`, `boost_messages`, `boost_feedback` +- Extension point: `boostProviderExtensionPoint` +- Service ref: `boostAiProviderServiceRef` +- Plugin ID: `boost` (used in `createBackendModule({ pluginId: 'boost', ... })`) + +### Testing + +Every feature ships with tests. Integration tests use real database and cache backends, not mocks. + +### Frontend + +- Composable routable extensions with `React.lazy()` at extension boundaries +- PatternFly design system components consistent with RHDH +- WCAG 2.1 AA accessibility +- Feature flags via `boost.features.*` in `app-config.yaml` + +## What not to do + +- Do not reference the `workspaces/augment/` codebase for implementation patterns — boost is a clean-room build +- Do not use `augment` as a prefix for any new identifiers (config keys, permissions, tables, etc.) +- Do not create raw `Map<>` caches — always use `coreServices.cache` +- Do not add authorization checks outside `permissions.authorize()` +- Do not add provider ID string checks in the frontend From 6dc9a2fb1b1ba43b8c9125d4ae755f3edc0a0e8d Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 4 Jun 2026 14:04:00 -0400 Subject: [PATCH 4/8] =?UTF-8?q?docs(boost):=20add=20AGENTS.md=20and=20fix?= =?UTF-8?q?=20case-sensitive=20Augment=E2=86=92Boost=20renames?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add AGENTS.md to instruct fullsend agents on boost's specification- driven development workflow, architecture rules, naming conventions, and anti-patterns. This enables fullsend's code agent to read OpenSpec specs before implementing issues. Fix remaining case-sensitive "Augment" references that describe boost's own forward-looking behavior (the prior rename pass only caught lowercase "augment." config/permission prefixes). Component names (AugmentErrorBoundary→BoostErrorBoundary, AugmentApiClient→ BoostApiClient), the SonataFlow callback header (X-Augment-Workflow-Callback→X-Boost-Workflow-Callback), and ~40 prose occurrences across specs and PRDs where "Augment" was the subject of boost's own requirements are now "Boost". Historical references to the Augment prototype (lessons learned, provenance metadata, design context) are intentionally preserved. Addresses fullsend review: https://github.com/redhat-developer/rhdh-plugins/pull/3292#pullrequestreview-4430087306 Signed-off-by: gabemontero Co-Authored-By: Claude Opus 4.6 --- .../specs/agent-gallery/spec.md | 2 +- .../specs/streaming-chat/spec.md | 2 +- .../specs/deployment/spec.md | 12 +++++----- .../specs/runtime-config/spec.md | 2 +- .../specs/white-label/spec.md | 2 +- .../specs/provider-abstraction/spec.md | 6 ++--- .../specs/access-control/spec.md | 4 ++-- .../specs/resilience/spec.md | 2 +- .../prd/agent-creation-discovery.md | 24 +++++++++---------- .../prd/ai-chat-interaction-experience.md | 2 +- .../prd/platform-operations-deployment.md | 4 ++-- .../prd/pluggable-ai-platform-architecture.md | 18 +++++++------- .../prd/security-safety-governance.md | 6 ++--- 13 files changed, 43 insertions(+), 43 deletions(-) diff --git a/workspaces/boost/openspec/changes/agent-creation-discovery/specs/agent-gallery/spec.md b/workspaces/boost/openspec/changes/agent-creation-discovery/specs/agent-gallery/spec.md index 08da947d3cd..3aac8e514b1 100644 --- a/workspaces/boost/openspec/changes/agent-creation-discovery/specs/agent-gallery/spec.md +++ b/workspaces/boost/openspec/changes/agent-creation-discovery/specs/agent-gallery/spec.md @@ -25,7 +25,7 @@ A full-featured agent browsing experience for the Kagenti provider. #### Scenario: First visit auto-open -- **WHEN** a user visits Augment with Kagenti provider and no agent is selected +- **WHEN** a user visits Boost with Kagenti provider and no agent is selected - **THEN** the agent catalog dialog auto-opens ### Requirement: Unified Agent List diff --git a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/streaming-chat/spec.md b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/streaming-chat/spec.md index eb5aa9856ed..061aad7dadc 100644 --- a/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/streaming-chat/spec.md +++ b/workspaces/boost/openspec/changes/ai-chat-interaction-experience/specs/streaming-chat/spec.md @@ -44,7 +44,7 @@ The chat interface degrades gracefully on errors. - **WHEN** an agent returns an error during a streaming response - **THEN** an `ErrorCard` is displayed inline within the message -- **AND** the page does not crash (protected by `AugmentErrorBoundary`) +- **AND** the page does not crash (protected by `BoostErrorBoundary`) - **AND** the conversation remains navigable ### Requirement: Conversation Auto-Save diff --git a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/deployment/spec.md b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/deployment/spec.md index b1a0986b747..7041170cecd 100644 --- a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/deployment/spec.md +++ b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/deployment/spec.md @@ -2,30 +2,30 @@ > **Status: Draft** — Pre-implementation specification. Subject to change during implementation. -Install and configure Augment in an RHDH or vanilla Backstage instance via two deployment paths. +Install and configure Boost in an RHDH or vanilla Backstage instance via two deployment paths. ## EXISTING Requirements ### Requirement: RHDH Dynamic Plugin Deployment -Deploy Augment as a dynamic plugin with zero code changes. +Deploy Boost as a dynamic plugin with zero code changes. #### Scenario: Dynamic plugin installation -- **WHEN** the administrator configures `dynamic-plugins.override.yaml` with Augment OCI plugin references +- **WHEN** the administrator configures `dynamic-plugins.override.yaml` with Boost OCI plugin references - **THEN** RHDH loads frontend, backend, and common packages dynamically via Scalprum - **AND** no code changes or application rebuilds are required -- **AND** Augment appears as a sidebar entry in RHDH +- **AND** Boost appears as a sidebar entry in RHDH #### Scenario: Dynamic plugin configuration -- **WHEN** the administrator sets up `app-config.yaml` with Augment configuration +- **WHEN** the administrator sets up `app-config.yaml` with Boost configuration - **THEN** provider settings, security mode, and base URLs are configured - **AND** the plugin validates configuration at startup against the declared schema ### Requirement: Backstage Static Plugin Deployment -Deploy Augment as a traditional Backstage plugin with npm packages. +Deploy Boost as a traditional Backstage plugin with npm packages. #### Scenario: Static plugin installation diff --git a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/runtime-config/spec.md b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/runtime-config/spec.md index 26cd59c96b5..4b364c69e4a 100644 --- a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/runtime-config/spec.md +++ b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/runtime-config/spec.md @@ -2,7 +2,7 @@ > **Status: Draft** — Pre-implementation specification. Subject to change during implementation. -Change Augment's behavior at runtime — model, system prompt, tools, caps, and more — without restarting. +Change Boost's behavior at runtime — model, system prompt, tools, caps, and more — without restarting. ## EXISTING Requirements diff --git a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/white-label/spec.md b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/white-label/spec.md index 98b5e6771a3..5f3d063c82d 100644 --- a/workspaces/boost/openspec/changes/platform-operations-deployment/specs/white-label/spec.md +++ b/workspaces/boost/openspec/changes/platform-operations-deployment/specs/white-label/spec.md @@ -2,7 +2,7 @@ > **Status: Draft** — Pre-implementation specification. Subject to change during implementation. -Customize the Augment experience to match the organization's brand — all at runtime, no deployment required. +Customize the Boost experience to match the organization's brand — all at runtime, no deployment required. ## EXISTING Requirements diff --git a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-abstraction/spec.md b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-abstraction/spec.md index 90512c53c3a..3ccb99ee0ef 100644 --- a/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-abstraction/spec.md +++ b/workspaces/boost/openspec/changes/pluggable-ai-platform-architecture/specs/provider-abstraction/spec.md @@ -2,13 +2,13 @@ > **Status: Draft** — Pre-implementation specification. Subject to change during implementation. -Augment abstracts AI platform backends behind a pluggable provider interface, enabling any AI platform to be integrated without forking the plugin. +Boost abstracts AI platform backends behind a pluggable provider interface, enabling any AI platform to be integrated without forking the plugin. ## EXISTING Requirements ### Requirement: AgenticProvider Interface -The `AgenticProvider` interface defines the contract between Augment and any AI platform backend. Chat and streaming are required capabilities; RAG, safety, evaluation, and conversation management are optional capability objects. +The `AgenticProvider` interface defines the contract between Boost and any AI platform backend. Chat and streaming are required capabilities; RAG, safety, evaluation, and conversation management are optional capability objects. #### Scenario: Provider implements required capabilities @@ -24,7 +24,7 @@ The `AgenticProvider` interface defines the contract between Augment and any AI ### Requirement: Extension Point Registration -Providers register via a Backstage extension point, requiring zero Augment source code modification. +Providers register via a Backstage extension point, requiring zero Boost source code modification. #### Scenario: External provider module registers via extension point diff --git a/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md b/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md index 1c2a400b57d..89f27bf82d3 100644 --- a/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md +++ b/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md @@ -2,7 +2,7 @@ > **Status: Draft** — Pre-implementation specification. Subject to change during implementation. -Multi-level security configuration controlling who accesses Augment, who has admin privileges, and how tool connections are authenticated. +Multi-level security configuration controlling who accesses Boost, who has admin privileges, and how tool connections are authenticated. ## EXISTING Requirements @@ -38,7 +38,7 @@ Unauthorized users see meaningful access-denied pages, not broken UIs. #### Scenario: SecurityGate blocks unauthorized access -- **WHEN** a user without `boost.access` permission navigates to Augment +- **WHEN** a user without `boost.access` permission navigates to Boost - **THEN** `SecurityGate` renders a meaningful access-denied page - **AND** the page explains what permission is needed and how to request access diff --git a/workspaces/boost/openspec/changes/security-safety-governance/specs/resilience/spec.md b/workspaces/boost/openspec/changes/security-safety-governance/specs/resilience/spec.md index 0f982a98621..eb8803a97b1 100644 --- a/workspaces/boost/openspec/changes/security-safety-governance/specs/resilience/spec.md +++ b/workspaces/boost/openspec/changes/security-safety-governance/specs/resilience/spec.md @@ -24,7 +24,7 @@ Per-message and page-level error isolation prevents cascading failures. - **WHEN** an agent or streaming error occurs - **THEN** `ErrorCard` is displayed inline on the affected message -- **AND** `AugmentErrorBoundary` prevents the entire page from crashing +- **AND** `BoostErrorBoundary` prevents the entire page from crashing - **AND** other messages and navigation remain functional ### Requirement: Transient Notifications diff --git a/workspaces/boost/specifications/prd/agent-creation-discovery.md b/workspaces/boost/specifications/prd/agent-creation-discovery.md index 3cab5126f21..2c9cf71305b 100644 --- a/workspaces/boost/specifications/prd/agent-creation-discovery.md +++ b/workspaces/boost/specifications/prd/agent-creation-discovery.md @@ -11,7 +11,7 @@ ## Why -An agentic AI platform is only as valuable as the agents running on it. Augment must support the full agent lifecycle — from initial creation through discovery by end users — across two fundamentally different personas: citizen developers who create agents visually and professional developers who build agents with code. +An agentic AI platform is only as valuable as the agents running on it. Boost must support the full agent lifecycle — from initial creation through discovery by end users — across two fundamentally different personas: citizen developers who create agents visually and professional developers who build agents with code. This PRD defines the four creation paths, the discovery and browsing experience, and MCP tool connectivity that powers agent capabilities. Together, these form the "supply side" of the agent ecosystem. @@ -99,7 +99,7 @@ All agent creation, gallery, and admin UI flows must align with RHDH usability a ### 3. Create an Agent — Umbrella (UC-7) -**Goal:** Create a new AI agent that serves users through the Augment chat interface. +**Goal:** Create a new AI agent that serves users through the Boost chat interface. Four creation methods converge to a unified `ChatAgent` model: @@ -171,7 +171,7 @@ All methods produce an agent visible in the gallery and available in chat. ### 7. Import an Existing Agent (UC-12) -**Goal:** Bring an already-built agent (container image or source repo) and make it available through Augment. +**Goal:** Bring an already-built agent (container image or source repo) and make it available through Boost. **Container image flow:** @@ -210,24 +210,24 @@ All methods produce an agent visible in the gallery and available in chat. ### 9. Skills Marketplace Integration -**Goal:** Integrate with an external skills marketplace (provided by a separate workspace) to browse, select, and deploy pre-built skills-based agents into the Augment environment. +**Goal:** Integrate with an external skills marketplace (provided by a separate workspace) to browse, select, and deploy pre-built skills-based agents into the Boost environment. -**Note:** Augment does not own or implement the skills marketplace itself. The marketplace is provided by another workspace/team. Augment is a consumer that proxies requests to the external skills catalog and handles the deployment of selected skills into the local Kagenti environment. +**Note:** Boost does not own or implement the skills marketplace itself. The marketplace is provided by another workspace/team. Boost is a consumer that proxies requests to the external skills catalog and handles the deployment of selected skills into the local Kagenti environment. **How it works:** 1. Admin navigates to the Skills section in the admin panel -2. Augment proxies browse/filter requests to the external skills catalog backend -3. Admin selects a skill → Augment generates the K8s deployment manifest with init container for OCI skill extraction +2. Boost proxies browse/filter requests to the external skills catalog backend +3. Admin selects a skill → Boost generates the K8s deployment manifest with init container for OCI skill extraction 4. Deploy skill agent to local namespace → deployment progress polling shows status -5. Deployed skill agents appear in the Augment gallery with a `DocsClaw` framework label and skill badge +5. Deployed skill agents appear in the Boost gallery with a `DocsClaw` framework label and skill badge **Integration architecture:** - `GET /skills` proxies to the external skills catalog backend (endpoint configured via `boost.skillsMarketplace.endpoint`) - `GET /skills/runtimes` and `GET /skills/domains` proxy filter metadata from the external catalog -- Augment handles deployment only: K8s manifest generation, OCI init containers, namespace scoping -- Deployed skills agents carry a `chatEndpoint` field for direct chat routing within Augment +- Boost handles deployment only: K8s manifest generation, OCI init containers, namespace scoping +- Deployed skills agents carry a `chatEndpoint` field for direct chat routing within Boost ### 10. Backstage Catalog Representation @@ -290,8 +290,8 @@ Boost uses the 4-stage model from the start — no legacy stage mappings or norm **Skills marketplace integration:** -- Augment proxies browse/filter requests to an external skills catalog backend (separate workspace) -- Augment owns deployment only: K8s manifest generation with OCI init containers +- Boost proxies browse/filter requests to an external skills catalog backend (separate workspace) +- Boost owns deployment only: K8s manifest generation with OCI init containers - Deployed skill agents carry `framework: 'docsclaw'` and `chatEndpoint` field **Kagenti admin surface:** diff --git a/workspaces/boost/specifications/prd/ai-chat-interaction-experience.md b/workspaces/boost/specifications/prd/ai-chat-interaction-experience.md index 457b569eb0a..efcb7b86a32 100644 --- a/workspaces/boost/specifications/prd/ai-chat-interaction-experience.md +++ b/workspaces/boost/specifications/prd/ai-chat-interaction-experience.md @@ -11,7 +11,7 @@ ## Why -Augment's core value proposition is enabling developers to have intelligent, grounded conversations with specialist AI agents — directly within their developer portal. Without a compelling chat experience, the platform has no user-facing value regardless of what's configured behind it. +Boost's core value proposition is enabling developers to have intelligent, grounded conversations with specialist AI agents — directly within their developer portal. Without a compelling chat experience, the platform has no user-facing value regardless of what's configured behind it. This PRD defines the primary interaction surface: the streaming chat interface, knowledge-grounded answers, human-in-the-loop approval controls, conversation history management, and developer debugging tools. Together, these capabilities form the "inner loop" of the developer-agent relationship. diff --git a/workspaces/boost/specifications/prd/platform-operations-deployment.md b/workspaces/boost/specifications/prd/platform-operations-deployment.md index 522783fe291..689abdaf344 100644 --- a/workspaces/boost/specifications/prd/platform-operations-deployment.md +++ b/workspaces/boost/specifications/prd/platform-operations-deployment.md @@ -158,7 +158,7 @@ All packages live at `rhdh-plugins/workspaces/boost/plugins/`: ### 4. Manage Runtime Configuration (UC-21) -**Goal:** Change Augment's behavior at runtime — model, system prompt, tools, caps, and more — without restarting. +**Goal:** Change Boost's behavior at runtime — model, system prompt, tools, caps, and more — without restarting. **Configuration engine:** @@ -194,7 +194,7 @@ All packages live at `rhdh-plugins/workspaces/boost/plugins/`: ### 5. White-Label the Portal (UC-22) -**Goal:** Customize the Augment experience to match the organization's brand — all at runtime. +**Goal:** Customize the Boost experience to match the organization's brand — all at runtime. **Customizable elements:** diff --git a/workspaces/boost/specifications/prd/pluggable-ai-platform-architecture.md b/workspaces/boost/specifications/prd/pluggable-ai-platform-architecture.md index 02bcbd144bc..d0786b067e7 100644 --- a/workspaces/boost/specifications/prd/pluggable-ai-platform-architecture.md +++ b/workspaces/boost/specifications/prd/pluggable-ai-platform-architecture.md @@ -11,9 +11,9 @@ ## Why -Enterprise customers run different AI platforms — and they change their minds. A platform that hard-codes a single AI backend becomes a liability: vendor lock-in, inability to evaluate alternatives, and deployment friction when the AI strategy evolves. Augment must be the experience layer that sits above any AI platform, not a client of one specific platform. +Enterprise customers run different AI platforms — and they change their minds. A platform that hard-codes a single AI backend becomes a liability: vendor lock-in, inability to evaluate alternatives, and deployment friction when the AI strategy evolves. Boost must be the experience layer that sits above any AI platform, not a client of one specific platform. -This PRD defines the pluggable provider architecture that makes Augment provider-agnostic: the abstraction interface, the normalized streaming protocol, runtime hot-swap, multi-agent orchestration via Llama Stack, and the framework-neutral Kagenti integration. +This PRD defines the pluggable provider architecture that makes Boost provider-agnostic: the abstraction interface, the normalized streaming protocol, runtime hot-swap, multi-agent orchestration via Llama Stack, and the framework-neutral Kagenti integration. ## What This Product Does @@ -23,7 +23,7 @@ Boost abstracts AI platform backends behind a provider interface. Each provider ### Professional Developer (Provider Integrator) -Implements the `AgenticProvider` interface to add a new AI platform backend. Creates a Backstage backend module that registers the provider — no modification to Augment source code required. +Implements the `AgenticProvider` interface to add a new AI platform backend. Creates a Backstage backend module that registers the provider — no modification to Boost source code required. ### Administrator @@ -69,7 +69,7 @@ Hot-swaps between configured providers at runtime. Monitors capability differenc - `ProviderDescriptor` declares the provider's ID, name, and supported capabilities - `AgenticProviderFactory` instantiates the provider from config - Registration via `boostProviderExtensionPoint` in a Backstage backend module -- No Augment source modification required +- No Boost source modification required **Built-in providers:** @@ -120,8 +120,8 @@ Hot-swaps between configured providers at runtime. Monitors capability differenc 2. Create `ProviderDescriptor` declaring ID, name, supported capabilities 3. Create `AgenticProviderFactory` that instantiates from config 4. Register via `boostProviderExtensionPoint` in a Backstage backend module -5. Deploy module alongside Augment backend -6. New provider appears in admin panel's provider switcher — zero Augment source changes +5. Deploy module alongside Boost backend +6. New provider appears in admin panel's provider switcher — zero Boost source changes **Stream normalization:** Implement a stream normalizer mapping native events to `NormalizedStreamEvent` types. @@ -233,7 +233,7 @@ Hot-swaps between configured providers at runtime. Monitors capability differenc ## Architecture Context -**Core design principle:** Augment is the **experience layer** — the AI frontend and orchestration surface. It does not run models, serve inference, or manage GPUs. Those come from the underlying AI platform (OpenShift AI, Kagenti infrastructure, or customer-provided backends). +**Core design principle:** Boost is the **experience layer** — the AI frontend and orchestration surface. It does not run models, serve inference, or manage GPUs. Those come from the underlying AI platform (OpenShift AI, Kagenti infrastructure, or customer-provided backends). **Provider capability system:** @@ -308,7 +308,7 @@ kagenti-entity-provider (independently deployable RHDH dynamic plugin) **Streaming pipeline (end-to-end):** ``` -ChatInput → AugmentApiClient → POST /chat/stream +ChatInput → BoostApiClient → POST /chat/stream → chatRoutes.ts → setupSseStream → createStreamEventForwarder → provider.chatStream() → provider normalizer → NormalizedStreamEvent → SSE → sseStreaming.ts @@ -335,4 +335,4 @@ ChatInput → AugmentApiClient → POST /chat/stream Derived from the Citi engagement. Key architecture principle: "Provider-agnostic. Multiple AI backends supported through a pluggable provider interface. No lock-in to any model serving platform or agent framework." -Citi runs their own AI infrastructure and needs to switch between providers as their AI strategy evolves. The pluggable architecture ensures Augment is the stable surface while backends change underneath. +Citi runs their own AI infrastructure and needs to switch between providers as their AI strategy evolves. The pluggable architecture ensures Boost is the stable surface while backends change underneath. diff --git a/workspaces/boost/specifications/prd/security-safety-governance.md b/workspaces/boost/specifications/prd/security-safety-governance.md index ecdb7d9db06..3e51804e379 100644 --- a/workspaces/boost/specifications/prd/security-safety-governance.md +++ b/workspaces/boost/specifications/prd/security-safety-governance.md @@ -74,7 +74,7 @@ Security and governance UI surfaces (access-denied pages, approval queues, revie ### 1. Define Security Posture and Access Control (UC-20) -**Goal:** Configure who can access Augment, who has admin privileges, and how tool connections and AI providers are authenticated. +**Goal:** Configure who can access Boost, who has admin privileges, and how tool connections and AI providers are authenticated. **Three security modes:** @@ -185,7 +185,7 @@ Draft → Pending → Published → Archived - Dual-mode: built-in lifecycle transitions OR SonataFlow-managed approval workflows - When SonataFlow is enabled, `promote` triggers a CloudEvents POST to start an external approval workflow -- SonataFlow callbacks via `X-Augment-Workflow-Callback: true` header execute the approved/rejected transition +- SonataFlow callbacks via `X-Boost-Workflow-Callback: true` header execute the approved/rejected transition - Callback loop prevention guards prevent re-triggering workflows on callback-driven transitions - Fail-closed: if workflow fails to start, agent reverts to Draft with 502 error - SonataFlow callbacks create a separate trust boundary — callback identity should be verified @@ -252,7 +252,7 @@ Draft → Pending → Published → Archived **Error handling:** -- `AugmentErrorBoundary` prevents page crashes +- `BoostErrorBoundary` prevents page crashes - `ErrorCard` displayed inline on per-message errors - Snackbar toasts via `useToast` for transient notifications From a972cf787706d11dd9e4604784d80ff203eb480b Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 4 Jun 2026 14:08:17 -0400 Subject: [PATCH 5/8] docs(boost): fix resource type count from 3 to 2 Only 2 resource types exist (boost-agent, boost-tool). Functional permissions don't define a resource type. Fixes 3 occurrences across fine-grained-permissions spec, security PRD, and security proposal. Addresses fullsend review on PR #3292. Signed-off-by: gabemontero Co-Authored-By: Claude Opus 4.6 --- .../openspec/changes/security-safety-governance/proposal.md | 2 +- .../specs/fine-grained-permissions/spec.md | 2 +- .../boost/specifications/prd/security-safety-governance.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/workspaces/boost/openspec/changes/security-safety-governance/proposal.md b/workspaces/boost/openspec/changes/security-safety-governance/proposal.md index f74d4b12c43..6c1abe6e54e 100644 --- a/workspaces/boost/openspec/changes/security-safety-governance/proposal.md +++ b/workspaces/boost/openspec/changes/security-safety-governance/proposal.md @@ -13,7 +13,7 @@ Enterprise AI platforms must treat security, safety, and governance as foundatio ### Fine-Grained Permissions -- 16 Backstage permissions across 3 resource types (`boost-agent`, `boost-tool`, plus functional permissions) +- 16 Backstage permissions across 2 resource types (`boost-agent`, `boost-tool`) plus functional permissions - Conditional rules: `IS_OWNER`, `IS_NOT_CREATOR`, `HAS_LIFECYCLE_STAGE` - `authorizeLifecycleAction` middleware as the sole authorization path — no scattered per-route guards - All authorization decisions use `permissions.authorize()` from day one 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 fb08a537a2a..531ea1ed52a 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 @@ -2,7 +2,7 @@ > **Status: Draft** — Pre-implementation specification. Subject to change during implementation. -Implement 16 fine-grained Backstage permissions across 3 resource types with conditional rules, using `permissions.authorize()` as the sole authorization mechanism. All authorization decisions go through Backstage RBAC from day one — no custom route-level governance layer. +Implement 16 fine-grained Backstage permissions across 2 resource types with conditional rules, using `permissions.authorize()` as the sole authorization mechanism. All authorization decisions go through Backstage RBAC from day one — no custom route-level governance layer. ## ADDED Requirements diff --git a/workspaces/boost/specifications/prd/security-safety-governance.md b/workspaces/boost/specifications/prd/security-safety-governance.md index 3e51804e379..d75ab25bf8c 100644 --- a/workspaces/boost/specifications/prd/security-safety-governance.md +++ b/workspaces/boost/specifications/prd/security-safety-governance.md @@ -38,7 +38,7 @@ Creates agents and submits them for governance review. Subject to ownership-base ### In Scope - Three security modes: `development-only-no-auth`, `plugin-only`, `full` -- Fine-grained RBAC via Backstage permissions (16 permissions, 3 resource types, conditional rules) +- Fine-grained RBAC via Backstage permissions (16 permissions, 2 resource types, conditional rules) - Agent lifecycle governance: 4-stage model (Draft → Pending → Published → Archived) with approval workflows - SonataFlow integration for external approval orchestration - Per-user Kagenti identity via RFC 8693 OAuth2 Token Exchange @@ -86,7 +86,7 @@ Security and governance UI surfaces (access-denied pages, approval queues, revie **Note:** The legacy mode name `none` is deprecated; deployments should use `development-only-no-auth`. A prominent warning is logged if this mode is detected in a non-development environment. -**Fine-grained RBAC (16 permissions across 3 resource types):** +**Fine-grained RBAC (16 permissions across 2 resource types):** | Permission | Resource Type | Conditional Rules | Description | | ----------------------- | ------------- | --------------------------------------- | --------------------------------------------------- | From ee17731029229f8afd02aed016aff2c68a9f8601 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 4 Jun 2026 14:10:52 -0400 Subject: [PATCH 6/8] docs(boost): align access-control spec with no-legacy-aliases stance The access-control spec had a scenario describing `none` as a working security mode, contradicting tasks 9.1-9.2 (no legacy aliases), task 10.8 (verify `none` is rejected), and the design doc. Since boost is a clean-room build with no prior `none` mode to deprecate, the spec now describes rejection behavior: `none` causes a startup error directing users to `development-only-no-auth`. Addresses fullsend review on PR #3292. Signed-off-by: gabemontero Co-Authored-By: Claude Opus 4.6 --- .../specs/access-control/spec.md | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md b/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md index 89f27bf82d3..87342068408 100644 --- a/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md +++ b/workspaces/boost/openspec/changes/security-safety-governance/specs/access-control/spec.md @@ -10,12 +10,19 @@ Multi-level security configuration controlling who accesses Boost, who has admin The plugin supports progressive security enforcement from development through production. -#### Scenario: Security mode `none` (development only) +#### Scenario: Security mode `development-only-no-auth` (development only) -- **WHEN** `boost.security.mode` is set to `none` +- **WHEN** `boost.security.mode` is set to `development-only-no-auth` - **THEN** the frontend shows no SecurityGate — all users pass as guest - **AND** the backend skips RBAC and treats everyone as admin - **AND** provider auth uses static token/TLS if configured +- **AND** if detected in a non-development environment, a prominent warning is logged at startup + +#### Scenario: Rejected legacy mode name `none` + +- **WHEN** `boost.security.mode` is set to `none` +- **THEN** boost fails to start with a clear error message +- **AND** the error directs the user to use `development-only-no-auth` instead #### Scenario: Security mode `plugin-only` (recommended production) @@ -134,14 +141,13 @@ Sensitive credentials are stored encrypted in the admin config database. ### Requirement: Security Mode Naming -The `none` mode name must clearly indicate its development-only nature. +The development security mode uses an explicit name that communicates its purpose. The legacy name `none` is not accepted. -#### Scenario: Renamed security mode with production warning +#### Scenario: Only valid mode names accepted -- **WHEN** `boost.security.mode` is set to `development-only-no-auth` (renamed from `none`) -- **THEN** behavior is identical to the current `none` mode -- **AND** if detected in a non-development environment, a prominent warning is logged at startup -- **AND** boost uses `development-only-no-auth` as the only name for this mode (no legacy aliases) +- **WHEN** `boost.security.mode` is set to any value +- **THEN** only `development-only-no-auth`, `plugin-only`, and `full` are accepted +- **AND** any other value (including `none`) causes a startup error with guidance on valid options ### Requirement: Identity Resolution From 0c5c4e30037044e791f351bed0d301acb81d31a8 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 4 Jun 2026 15:06:08 -0400 Subject: [PATCH 7/8] docs(boost): distinguish Backstage catalog polling from upstream refresh Clarify the two-layer polling model for entity providers: 1. Backstage catalog infrastructure polls entity providers on its own schedule (managed by the catalog framework, not boost) 2. Each entity provider independently manages how often it fetches from its upstream API (Kagenti, Llama Stack) The upstream refresh interval is now configurable via app-config.yaml rather than hardcoded (defaults: 60s models, 5m agents/tools/MCP, 10m vector stores). Updated design.md Decision 2, tasks.md task 1e.4, and catalog-entities/spec.md scenarios for both Kagenti and Llama Stack entity providers. Signed-off-by: gabemontero Co-Authored-By: Claude Opus 4.6 --- .../openspec/changes/agent-creation-discovery/design.md | 8 +++++--- .../specs/catalog-entities/spec.md | 7 +++++-- .../openspec/changes/agent-creation-discovery/tasks.md | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/workspaces/boost/openspec/changes/agent-creation-discovery/design.md b/workspaces/boost/openspec/changes/agent-creation-discovery/design.md index f528585e3b3..db2bb3b57e8 100644 --- a/workspaces/boost/openspec/changes/agent-creation-discovery/design.md +++ b/workspaces/boost/openspec/changes/agent-creation-discovery/design.md @@ -33,9 +33,11 @@ Use `kind: Component, spec.type: ai-agent` for agents and `kind: Resource, spec. Entity providers are separate packages registered as Backstage backend services, each independently deployable as an RHDH dynamic plugin: -- `kagenti-entity-provider` — `KagentiAgentEntityProvider` (5m), `KagentiToolEntityProvider` (5m) -- `llamastack-entity-provider` — `LlamaStackModelEntityProvider` (60s), `LlamaStackAgentEntityProvider` (5m) -- Core plugin: `McpEntityProvider` (5m), `VectorStoreEntityProvider` (10m) — cross-cutting +- `kagenti-entity-provider` — `KagentiAgentEntityProvider`, `KagentiToolEntityProvider` +- `llamastack-entity-provider` — `LlamaStackModelEntityProvider`, `LlamaStackAgentEntityProvider` +- Core plugin: `McpEntityProvider`, `VectorStoreEntityProvider` — cross-cutting + +**Two-layer polling model:** Backstage's catalog infrastructure polls entity providers on its own schedule. Independently, each entity provider manages its own upstream refresh interval — how often it fetches from the external API (Kagenti, Llama Stack). When Backstage polls the entity provider, the provider returns its most recently cached upstream data rather than blocking on a live API call every time. The upstream refresh interval is configurable via `app-config.yaml` (defaults: 60s for models, 5m for agents/tools/MCP servers, 10m for vector stores). **Standalone mode:** Install entity providers without boost to get catalog discoverability for teams already using Llama Stack or Kagenti. diff --git a/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md b/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md index 2aa8b64fb10..06af029581f 100644 --- a/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md +++ b/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md @@ -37,16 +37,19 @@ Agents are represented as Backstage catalog entities with lifecycle, ownership, #### Scenario: Kagenti module emits agent entities -- **WHEN** the `KagentiAgentEntityProvider` (inside the Kagenti provider module) runs on its scheduled interval +- **WHEN** the `KagentiAgentEntityProvider` (inside the Kagenti provider module) refreshes its upstream data - **THEN** it polls the Kagenti API for all agents across configured namespaces +- **AND** the upstream refresh interval is configurable via `app-config.yaml` (default: 5m) +- **AND** Backstage's catalog infrastructure polls the entity provider on its own independent schedule - **AND** it emits catalog entities with `kind: Component, spec.type: ai-agent` (or `kind: AIContext` when upstream is available) - **AND** agent capabilities, LLM demands, and MCP demands map to `spec.dependsOn` relations - **AND** the catalog is the source of truth for agent data — no in-memory cache needed #### Scenario: Llama Stack module emits agent entities -- **WHEN** the `LlamaStackAgentEntityProvider` (inside the Llama Stack provider module) runs on its scheduled interval +- **WHEN** the `LlamaStackAgentEntityProvider` (inside the Llama Stack provider module) refreshes its upstream data - **THEN** it reads configured agents from YAML/admin config +- **AND** the upstream refresh interval is configurable via `app-config.yaml` (default: 5m) - **AND** it emits catalog entities for each configured agent with their tool sets and handoff targets #### Scenario: Agent lifecycle reflected in catalog diff --git a/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md b/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md index f052d77c5de..3f494edc45f 100644 --- a/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md +++ b/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md @@ -37,7 +37,7 @@ - [ ] 1e.1 Map agent `createdBy` → catalog entity `spec.owner` for RBAC integration - [ ] 1e.2 Map 4-stage lifecycle (Draft/Pending/Published/Archived) → catalog lifecycle state (experimental/experimental/production/deprecated) in entity annotations - [ ] 1e.3 Create `CatalogProcessor` validators for ai-agent, ai-model, mcp-server, vector-store, ai-tool types -- [ ] 1e.4 Configure scheduled task runners per provider (60s models, 5m agents/MCP/tools, 10m vector stores) +- [ ] 1e.4 Implement configurable upstream refresh intervals per entity provider via `app-config.yaml` (defaults: 60s models, 5m agents/MCP/tools, 10m vector stores); Backstage catalog polling is managed by the catalog infrastructure independently ## 2. Catalog Integration (P2) From 2355bcebfbdd489cc3e49eed94b734b4a7c722e6 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 4 Jun 2026 15:33:48 -0400 Subject: [PATCH 8/8] docs(boost): clarify tool taxonomy and adopt upstream MCP server entity kind Three-way tool distinction made explicit throughout specs: - Kagenti Tools (ai-tool): K8s workloads with lifecycle governance (boost-tool permission resource type) - MCP Servers (mcp-server): registered protocol endpoints, no lifecycle - MCP Tools: runtime-discovered children of MCP servers, not independent catalog entities MCP servers now prefer upstream kind: API, spec.type: mcp-server with spec.remotes from @backstage/plugin-catalog-backend-module-ai-model (backstage#34016, merged). Falls back to kind: Resource if the model module is not installed. Updated: - catalog-entities/spec.md: entity type table, notes on tools and MCP server kind - design.md Decision 1: upstream kinds where available - tasks.md 1d.1: McpEntityProvider with API/Resource fallback - fine-grained-permissions/spec.md: boost-tool = Kagenti tools only Signed-off-by: gabemontero Co-Authored-By: Claude Opus 4.6 --- .../changes/agent-creation-discovery/design.md | 4 ++-- .../specs/catalog-entities/spec.md | 18 +++++++++++------- .../changes/agent-creation-discovery/tasks.md | 2 +- .../specs/fine-grained-permissions/spec.md | 2 +- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/workspaces/boost/openspec/changes/agent-creation-discovery/design.md b/workspaces/boost/openspec/changes/agent-creation-discovery/design.md index db2bb3b57e8..4bf68b7303d 100644 --- a/workspaces/boost/openspec/changes/agent-creation-discovery/design.md +++ b/workspaces/boost/openspec/changes/agent-creation-discovery/design.md @@ -25,9 +25,9 @@ Boost integrates with an external skills marketplace (provided by a separate wor ## Decisions -### Decision 1: Use existing kinds with path to upstream +### Decision 1: Use upstream kinds where available, existing kinds as fallback -Use `kind: Component, spec.type: ai-agent` for agents and `kind: Resource, spec.type: ai-model|mcp-server|vector-store|ai-tool` for infrastructure resources. When upstream `AIContext` and `API v1alpha2` land, adopt those kinds. Custom `CatalogProcessor` validators support both during transition. Tools are added as `kind: Resource, spec.type: ai-tool` to enable tool lifecycle permissions via catalog RBAC. +Use `kind: Component, spec.type: ai-agent` for agents. For MCP servers, prefer `kind: API, spec.type: mcp-server` using the upstream `McpServerApiEntity` from `@backstage/plugin-catalog-backend-module-ai-model` ([backstage#34016](https://github.com/backstage/backstage/pull/34016), merged) — fall back to `kind: Resource, spec.type: mcp-server` if the model module is not installed. Use `kind: Resource` for models (`ai-model`), vector stores (`vector-store`), and Kagenti tools (`ai-tool`). When upstream `AIContext` lands, adopt it for agents. Custom `CatalogProcessor` validators support both current and future kinds during transitions. ### Decision 2: Entity providers as independently deployable backend services diff --git a/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md b/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md index 06af029581f..500d31a470d 100644 --- a/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md +++ b/workspaces/boost/openspec/changes/agent-creation-discovery/specs/catalog-entities/spec.md @@ -12,13 +12,17 @@ NOTE: These recommendations align with in-flight upstream Backstage initiatives: The specifications below use existing Backstage kinds (`Resource`, `Component`) as the primary implementation path, with adoption of upstream kinds when they land. Custom `CatalogProcessor` validators support both during transition. **Entity type strategy:** -| Domain Object | Immediate Kind | `spec.type` | Future Kind (upstream) | -|---|---|---|---| -| AI Agents | `Component` | `ai-agent` | `AIContext` | -| AI Models | `Resource` | `ai-model` | `API` (v1alpha2 discriminated union) | -| MCP Servers | `Resource` | `mcp-server` | `API` (v1alpha2 discriminated union) | -| Vector Stores | `Resource` | `vector-store` | (no upstream equivalent planned) | -| Tools | `Resource` | `ai-tool` | (no upstream equivalent planned) | +| Domain Object | Preferred Kind | `spec.type` | Fallback Kind | Notes | +|---|---|---|---|---| +| AI Agents | `Component` | `ai-agent` | — | Future: `AIContext` when upstream lands | +| AI Models | `Resource` | `ai-model` | — | Future: `API` v1alpha2 discriminated union | +| MCP Servers | `API` | `mcp-server` | `Resource` | Upstream `McpServerApiEntity` available via `@backstage/plugin-catalog-backend-module-ai-model` ([backstage#34016](https://github.com/backstage/backstage/pull/34016), merged). Uses `spec.remotes: {type, url}[]` instead of `spec.definition`. Fall back to `kind: Resource, spec.type: mcp-server` if the catalog model module is not installed. | +| Vector Stores | `Resource` | `vector-store` | — | No upstream equivalent planned | +| Kagenti Tools | `Resource` | `ai-tool` | — | No upstream equivalent planned | + +**Note on MCP Server entity kind:** When `@backstage/plugin-catalog-backend-module-ai-model` is installed, MCP servers use `kind: API, spec.type: mcp-server` with `spec.remotes` for transport endpoints. The `McpEntityProvider` should detect whether the model module is available and emit the appropriate kind. Use `isMcpServerApiEntity` type guard from `@backstage/catalog-model` when available. + +**Note on tools:** "Kagenti Tools" (`ai-tool`) are K8s workloads with lifecycle governance (`boost-tool` permission resource type). "MCP Servers" (`mcp-server`) are registered protocol endpoints. Individual MCP tools (discovered at runtime via MCP `tools/list`) are not separate catalog entities — they are nested data within their parent MCP server. Entity providers are **independently deployable Backstage backend services**, each packaged as its own RHDH dynamic plugin (`llamastack-entity-provider`, `kagenti-entity-provider`). They are registered as backend services per the [Backstage backend system architecture](https://backstage.io/docs/backend-system/architecture/services/). diff --git a/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md b/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md index 3f494edc45f..627b1f06e54 100644 --- a/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md +++ b/workspaces/boost/openspec/changes/agent-creation-discovery/tasks.md @@ -28,7 +28,7 @@ ### 1d. Core plugin entity providers (cross-cutting) -- [ ] 1d.1 Implement `McpEntityProvider` reading MCP server configs from admin DB (kind: Resource, spec.type: mcp-server) +- [ ] 1d.1 Implement `McpEntityProvider` reading MCP server configs from admin DB — prefer `kind: API, spec.type: mcp-server` with `spec.remotes` (upstream `McpServerApiEntity` from `@backstage/plugin-catalog-backend-module-ai-model`); fall back to `kind: Resource, spec.type: mcp-server` if model module is not installed - [ ] 1d.2 Implement `VectorStoreEntityProvider` reading vector store configs (kind: Resource, spec.type: vector-store) - [ ] 1d.3 Register both via `catalogProcessingExtensionPoint` in core plugin 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 531ea1ed52a..9b1dba87cbe 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 @@ -43,7 +43,7 @@ RBAC policies govern agent lifecycle transitions with ownership and separation-o ### Requirement: Tool Lifecycle Permissions (Resource-Based) -RBAC policies govern tool lifecycle transitions. +RBAC policies govern Kagenti tool lifecycle transitions. The `boost-tool` resource type represents Kagenti tools (K8s workloads with lifecycle governance) — not MCP servers or MCP tools. MCP servers are registered endpoints without lifecycle permissions; MCP tools are runtime-discovered children of MCP servers with no independent lifecycle. #### Scenario: Tool permission definitions