Skip to content

feat(#3297): add boost-common types/permissions and boost-node service ref#3402

Open
fullsend-ai-coder[bot] wants to merge 3 commits into
mainfrom
agent/3297-boost-common-node
Open

feat(#3297): add boost-common types/permissions and boost-node service ref#3402
fullsend-ai-coder[bot] wants to merge 3 commits into
mainfrom
agent/3297-boost-common-node

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

Scaffold the two foundation packages for the boost workspace:

boost-common (common-library):

  • AgenticProvider, ProviderDescriptor, ProviderCapabilities interfaces
  • NormalizedStreamEvent discriminated union (19 event types)
  • ConversationSummary, ConversationDetails, InputItem types
  • ChatRequest, ChatResponse, ResponseUsage types
  • 16 resource permissions (10 agent + 5 tool + 1 kagenti-infra)
  • 5 functional permissions (chat.read/create, documents/mcp/config)
  • Resource types: boost-agent, boost-tool
  • Conditional rule constants: IS_OWNER, IS_NOT_CREATOR, HAS_LIFECYCLE_STAGE
  • No dependency on @backstage/backend-plugin-api (browser-safe)

boost-node (node-library):

  • boostAiProviderServiceRef via createServiceRef (id: boost.ai-provider)
  • Depends on @backstage/backend-plugin-api (backend-only)
  • Depends on boost-common for the AgenticProvider type parameter

The serviceRef lives in boost-node (not boost-common) to avoid pulling @backstage/backend-plugin-api into browser bundles, per PR #3396 review feedback and Backstage convention (plugin-catalog-common + plugin-catalog-node).


Closes #3297

Post-script verification

  • Branch is not main/master (agent/3297-boost-common-node)
  • Secret scan passed (gitleaks — 6c4b03802b506c2f86b0c210d0d622b3053c073f..HEAD)
  • Pre-commit hooks passed (authoritative run on runner)
  • Tests ran inside sandbox

…e ref

Scaffold the two foundation packages for the boost workspace:

boost-common (common-library):
- AgenticProvider, ProviderDescriptor, ProviderCapabilities interfaces
- NormalizedStreamEvent discriminated union (19 event types)
- ConversationSummary, ConversationDetails, InputItem types
- ChatRequest, ChatResponse, ResponseUsage types
- 16 resource permissions (10 agent + 5 tool + 1 kagenti-infra)
- 5 functional permissions (chat.read/create, documents/mcp/config)
- Resource types: boost-agent, boost-tool
- Conditional rule constants: IS_OWNER, IS_NOT_CREATOR, HAS_LIFECYCLE_STAGE
- No dependency on @backstage/backend-plugin-api (browser-safe)

boost-node (node-library):
- boostAiProviderServiceRef via createServiceRef (id: boost.ai-provider)
- Depends on @backstage/backend-plugin-api (backend-only)
- Depends on boost-common for the AgenticProvider type parameter

The serviceRef lives in boost-node (not boost-common) to avoid pulling
@backstage/backend-plugin-api into browser bundles, per PR #3396 review
feedback and Backstage convention (plugin-catalog-common + plugin-catalog-node).

Closes #3297
@fullsend-ai-coder fullsend-ai-coder Bot requested review from a team, durandom and gabemontero as code owners June 15, 2026 20:25
@rhdh-gh-app

rhdh-gh-app Bot commented Jun 15, 2026

Copy link
Copy Markdown

Missing Changesets

The following package(s) are changed by this PR but do not have a changeset:

  • @red-hat-developer-hub/backstage-plugin-boost-common
  • @red-hat-developer-hub/backstage-plugin-boost-node

See CONTRIBUTING.md for more information about how to add changesets.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-boost-common workspaces/boost/plugins/boost-common none v0.1.1
@red-hat-developer-hub/backstage-plugin-boost-node workspaces/boost/plugins/boost-node none v0.1.0

@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

⚠️ JUnit XML file not found

The CLI was unable to find any JUnit XML files to upload.
For more help, visit our troubleshooting guide.

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 15, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:27 PM UTC · Completed 8:41 PM UTC
Commit: 6c4b038 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [stale-doc] workspaces/boost/AGENTS.md:76 — The package structure table states boostAiProviderServiceRef belongs in boost-common, but this PR correctly places it in the new boost-node package (per Backstage convention to keep @backstage/backend-plugin-api out of browser bundles). Additionally, boost-node is not listed in the table at all. Update the table to add a boost-node row and move the service ref description there.

  • [stale-doc] workspaces/boost/README.md:31 — The directory structure diagram states plugins/ # Plugin packages (not yet created) but boost-common already exists on main and boost-node is being added by this PR. The Plugins table (lines 42-44) still shows only _coming soon_. Update both to reflect the actual packages.

Low

  • [scope-exceeded] workspaces/boost/plugins/boost-common/src/permissions.ts — The linked issue (boost-common and boost-node — Shared types, service ref, and permission definitions (issue 1 of 15) #3297) security task 1.1 specifies 16 permissions, but the PR defines 21 (10 agent + 5 tool + 1 infra + 5 functional). The 5 additional functional permissions (chat.read, chat.create, documents.manage, mcp.manage, config.manage) appear necessary for a complete authorization model but exceed the stated authorization.

  • [naming-convention] workspaces/boost/plugins/boost-common/src/types.ts — Types mix snake_case and camelCase property naming: ResponseUsage uses input_tokens/output_tokens/total_tokens, InputItem uses call_id, and ConversationDetails output items use call_id/server_label/file_id, while streaming event interfaces use camelCase (callId, responseId, serverLabel). This appears to be a deliberate wire-format compatibility choice (matching OpenAI-style API responses) but should be documented with a comment explaining the convention split.

  • [test-inadequate] workspaces/boost/plugins/boost-common/src/index.test.ts — The NormalizedStreamEvent type test exercises only 5 of 19 event variants (stream.started, stream.text.delta, stream.text.done, stream.error, stream.completed). While TypeScript compilation catches type-level errors, adding instances of all 19 variants would provide stronger regression coverage.

  • [pattern-inconsistency] workspaces/boost/plugins/boost-common/src/index.tsboost-common uses explicit named re-exports (export { x, y } from / export type { a, b } from) while sibling common packages (lightspeed-common, orchestrator-common) use barrel re-exports (export * from). Explicit exports are arguably better for API surface control but deviate from the established codebase pattern.

Info

  • [pattern-inconsistency] workspaces/boost/plugins/boost-common/src/permissions.ts — ASCII-art section separators (// =====...=====) are used throughout permissions.ts and types.ts but not in sibling packages. Consistent within this PR.

  • [doc-style] workspaces/boost/plugins/boost-common/src/types.ts — Streaming event interfaces use single-line JSDoc with inline @public while provider types use multi-line JSDoc with @public on its own line. Minor inconsistency within the file.

  • [sub-agent-failure] The security sub-agent could not access PR branch files and produced findings based on the base branch only. Manual verification of the diff confirms no security concerns: the PR contains only TypeScript type definitions and Backstage permission constants with no runtime security surface.

Previous run

Review

Findings

Low

  • [logic-error] workspaces/boost/plugins/boost-common/src/permissions.ts:362 — The boostResourcePermissions array name suggests all 16 entries are resource-scoped, but 4 (boostAgentListPermission, boostAgentRegisterPermission, boostAgentConfigurePermission, boostKagentiAdminPermission) are BasicPermission without a resourceType. The JSDoc already clarifies the actual composition ("10 agent + 5 tool + 1 kagenti-infra") and the as const tuple type provides compile-time safety, so runtime risk is low. Consider renaming to boostLifecyclePermissions or updating the JSDoc to avoid the term "resource permissions."

  • [edge-case] workspaces/boost/plugins/boost-common/src/types.ts:350StreamToolCompletedEvent has an optional error field while StreamToolFailedEvent has a required error field. A tool finishing with an error could be represented as either event type. Consumers with exhaustive switch matching on type may handle errors in stream.tool.failed but miss error cases in stream.tool.completed. Consider documenting the semantic distinction (e.g., partial success vs. total failure) so future consumers know to check error on completed events.

Info

  • [test-adequacy] workspaces/boost/plugins/boost-node/src/index.test.ts:20 — The boost-node test suite verifies only id and scope. Consider adding a compile-time type assertion for the AgenticProvider type parameter.

  • [sub-agent-failure] N/A — The intent-coherence, style-conventions, cross-repo-contracts, and docs-currency sub-agents did not return findings: model claude-sonnet-4-5@20250929 unavailable on vertex deployment. These are sonnet-tier dimensions; the safety-critical opus-tier dimensions (correctness, security) completed successfully.

Previous run (2)

Review

Findings

Medium

  • [api-contract] workspaces/boost/plugins/boost-common/src/types.ts:283ConversationSummary.createdAt and ConversationDetails.createdAt (line 309) are typed as Date, but these interfaces describe data that will cross JSON serialization boundaries. JSON.stringify(new Date()) produces a string, and JSON.parse does not revive it back to a Date object. Any consumer calling Date methods (e.g., .getTime(), .toLocaleDateString()) on the deserialized value will get a runtime TypeError.
    Remediation: Change createdAt: Date to createdAt: string (ISO 8601) in both interfaces, or document that consumers must revive the field.

  • [rbac-violation] workspaces/boost/plugins/boost-common/src/permissions.ts:169boostAgentConfigurePermission is a basic (non-resource-scoped) permission despite controlling per-agent configuration. Without resourceType, conditional rules like IS_OWNER cannot be applied. Any user granted this permission can configure ALL agents, which is inconsistent with the other 7 agent mutation permissions that are all scoped to RESOURCE_TYPE_BOOST_AGENT.
    Remediation: Add resourceType: RESOURCE_TYPE_BOOST_AGENT and type as ResourcePermission<'boost-agent'> to enable ownership-based conditional rules.

Low

  • [api-contract] workspaces/boost/plugins/boost-common/src/permissions.ts:361boostResourcePermissions is documented as "16 resource permissions" but 4 of its entries are BasicPermission (no resourceType). The as const tuple type preserves element types so this is a naming/documentation inaccuracy rather than a type-safety bug. Consider renaming to boostLifecyclePermissions or fixing the JSDoc.

  • [forward-compatibility] workspaces/boost/plugins/boost-common/src/types.ts:32ProviderCapabilities has 12 required boolean fields. Adding a new capability requires all implementations to update. Acceptable for a v0.1.0 scaffold but worth noting for future evolution.

  • [forward-compatibility] workspaces/boost/plugins/boost-common/src/types.ts:506StreamFormField, StreamFormDescriptor, StreamSecretDemand, and StreamCitationReference use open index signatures [key: string]: unknown while other interfaces are strictly shaped. This appears intentional for extensible external data but is worth documenting.

  • [api-shape] workspaces/boost/plugins/boost-common/src/types.ts:260ResponseUsage uses snake_case (input_tokens, output_tokens, total_tokens) while every other interface uses camelCase. Likely mirrors upstream LLM API conventions but inconsistent with the file's own patterns.

  • [api-shape] workspaces/boost/plugins/boost-common/src/types.ts:155listModels() return type uses snake_case (owned_by, model_type), same inconsistency as ResponseUsage.

  • [forward-compatibility] workspaces/boost/plugins/boost-common/src/types.ts:70ProviderConfigField.type is a closed union. Adding new field types (e.g., 'textarea', 'password') would require consumers with exhaustive switches to update.

  • [spec_deviation] workspaces/boost/plugins/boost-node/src/services.ts:34 — AGENTS.md documents boostAiProviderServiceRef as living in boost-common, but the implementation correctly places it in boost-node to avoid pulling @backstage/backend-plugin-api into browser bundles. AGENTS.md should be updated.

  • [rbac-violation] workspaces/boost/plugins/boost-common/src/permissions.ts:257boostKagentiAdminPermission uses action 'update' which is shared with many other boost permissions. Backstage RBAC matches on permission name, so this is an informational note about policy configuration.

  • [api-design] workspaces/boost/plugins/boost-common/src/types.ts:155listModels() and testModel() return inline anonymous object types. Consumers cannot reference these return types by name. Consider extracting into named interfaces.

Info

  • [rbac-violation] workspaces/boost/plugins/boost-common/src/permissions.ts:336 — Conditional rule constants (IS_OWNER, IS_NOT_CREATOR, HAS_LIFECYCLE_STAGE) are string constants with no compile-time binding to their corresponding permissions. Enforcement depends entirely on the boost-backend implementation.

  • [data-exposure] workspaces/boost/plugins/boost-common/src/types.ts:519StreamAuthRequiredEvent exposes auth details including OAuth URLs and secret demands. Backend implementations must sanitize before sending to clients.

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Jun 15, 2026
@gabemontero

Copy link
Copy Markdown
Contributor

/fs-fix CI fails because report.api.md is missing for the new boost-common plugin. Run yarn build:api-reports from the boost workspace root and commit the generated plugins/boost-common/report.api.md. See how other workspaces do it: workspaces/lightspeed/plugins/lightspeed-common/report.api.md. If further CI steps fail after that (prettier, lint, tsc), run yarn chores from the workspace root to fix the full cascade in one pass.

@fullsend-ai-coder

fullsend-ai-coder Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 9:24 PM UTC · Completed 9:53 PM UTC
Commit: 6c4b038 · View workflow run →

- Escape '>' in TSDoc comments for boostAgentPromotePermission and
  boostAgentApprovePermission to fix tsdoc-escape-greater-than warnings
  that blocked API report generation
- Regenerate boost-common/report.api.md with full API surface
- Add missing boost-node/report.api.md

Addresses review feedback on #3402
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 1 (human-triggered)

Generated missing API reports for boost-common and boost-node plugins. Fixed TSDoc escape warnings in permissions.ts that were blocking report generation. All tests pass (32/32), linting clean, prettier clean, tsc clean.

Fixed (3):

  1. missing report.api.md for boost-common plugin (workspaces/boost/plugins/boost-common/report.api.md): Regenerated report.api.md with full API surface after fixing TSDoc escape warnings in permissions.ts
  2. missing report.api.md for boost-node plugin (workspaces/boost/plugins/boost-node/report.api.md): Generated new report.api.md for boost-node package via yarn build:api-reports
  3. tsdoc-escape-greater-than warnings blocking API report generation (workspaces/boost/plugins/boost-common/src/permissions.ts): Escaped '>' as '>' in TSDoc comments for boostAgentPromotePermission (line 70) and boostAgentApprovePermission (line 84) to fix tsdoc-escape-greater-than warnings

Tests: passed

Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 15, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 9:54 PM UTC · Completed 10:03 PM UTC
Commit: 6c4b038 · View workflow run →

* @public
*/
export const boostResourcePermissions = [
// Agent permissions (10)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] logic-error

The boostResourcePermissions array name suggests all 16 entries are resource-scoped, but 4 are BasicPermission without resourceType. The JSDoc and TypeScript as-const tuple provide compile-time safety, so runtime risk is low. Consider renaming or updating the JSDoc.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/fs-fix please act upon review comment #3402 (comment) and rename boostResourcePermissions to boostPermissions

type: string;
/** Item identifier */
id?: string;
/** Role of the item author */

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] edge-case

StreamToolCompletedEvent has optional error while StreamToolFailedEvent has required error. A tool finishing with an error could be represented as either event type, risking silent error swallowing in consumers. Document the semantic distinction.

import { boostAiProviderServiceRef } from './index';

describe('boost-node', () => {
describe('boostAiProviderServiceRef', () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[info] test-adequacy

The boost-node test suite verifies only id and scope. Consider adding a compile-time type assertion for the AgenticProvider type parameter.

@fullsend-ai-review fullsend-ai-review Bot added ready-for-merge All reviewers approved — ready to merge and removed requires-manual-review Review requires human judgment labels Jun 15, 2026
@gabemontero

Copy link
Copy Markdown
Contributor

/fs-fix please act upon review comment #3402 (comment) and reorganize boostResourcePermissions as boostAgentPermissions, boostToolPermissions, and boostInfraPermissions

@fullsend-ai-coder

fullsend-ai-coder Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 10:04 PM UTC · Completed 10:34 PM UTC
Commit: daa1e8b · View workflow run →

Reorganize the monolithic boostResourcePermissions (16 entries) into
three focused arrays per review feedback:
- boostAgentPermissions (10 agent permissions)
- boostToolPermissions (5 tool permissions)
- boostInfraPermissions (1 kagenti infra permission)

The top-level boostPermissions now spreads all three plus
boostFunctionalPermissions, preserving the same 21-entry total.

Addresses review feedback on #3402
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 2 (human-triggered)

Reorganized boostResourcePermissions into boostAgentPermissions, boostToolPermissions, and boostInfraPermissions per human instruction. All 32 tests pass.

Fixed (1):

  1. boostResourcePermissions name is misleading — contains mix of BasicPermission and ResourcePermission (workspaces/boost/plugins/boost-common/src/permissions.ts): Split boostResourcePermissions into three focused arrays: boostAgentPermissions (10 agent permissions), boostToolPermissions (5 tool permissions), and boostInfraPermissions (1 kagenti infra permission). Updated boostPermissions to spread all three. Updated exports in index.ts, tests in index.test.ts, and API report.

Tests: passed

Updated by fullsend fix agent

@fullsend-ai-review

Copy link
Copy Markdown

🤖 Review · Started 10:35 PM UTC
Commit: daa1e8b · View workflow run →

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
15.2% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed ready-for-merge All reviewers approved — ready to merge labels Jun 16, 2026
@fullsend-ai-review

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 10:35 PM UTC · Completed 10:47 PM UTC
Commit: daa1e8b · View workflow run →

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

requires-manual-review Review requires human judgment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

boost-common and boost-node — Shared types, service ref, and permission definitions (issue 1 of 15)

1 participant