Skip to content

feat(adlc): move ADLC extension kinds to /api/hypershell/ext/ URL prefix - #462

Merged
markturansky merged 9 commits into
mainfrom
feat/adlc-agent-runtime-spec
Oct 7, 2026
Merged

markturansky merged 9 commits into
mainfrom
feat/adlc-agent-runtime-spec

Conversation

@markturansky

Copy link
Copy Markdown
Collaborator

Summary

  • Bumps rh-trex-ai to the commit that introduces RegisterPrefixedRoutes (rh-trex-ai#62)
  • Migrates all six ADLC extension kinds off the shared /v1 surface onto a distinct /ext prefix:
    • /api/hypershell/ext/agent_runtimes
    • /api/hypershell/ext/inference_routes
    • /api/hypershell/ext/provider_bindings
    • /api/hypershell/ext/provider_specs
    • /api/hypershell/ext/sandbox_templates
    • /api/hypershell/ext/secret_sources
  • Core gateway-management kinds (/v1/gateways, /v1/managed_clusters, etc.) are unchanged
  • The /ext subrouter carries the identical middleware stack as /v1 (metrics, auth/authz, DB transaction, compression)

Why /ext

These ADLC kinds are intentionally versioned and governed separately from the core gateway-management surface. A distinct URL prefix makes that boundary explicit without requiring a separate server process. The prefix is chosen by the downstream project - the framework does not hardcode it.

Test plan

  • go build ./... passes
  • go vet ./... passes
  • CI green

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository YAML (base), Central YAML (inherited)
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 5f26bb47-9f4f-4509-b3a4-d4f342560cde

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@hypershell-delivery

hypershell-delivery Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Amber review: comment

Amber review

Status: Complete

View the submitted review.

hypershell-delivery[bot]

This comment was marked as outdated.

@hypershell-delivery hypershell-delivery Bot added the amber/changes-requested Amber requested changes on this PR label Oct 7, 2026
@markturansky
markturansky force-pushed the feat/adlc-agent-runtime-spec branch from f2f6b73 to e7fd074 Compare October 7, 2026 12:24
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

HyperShell environment destroyed

This ephemeral OpenShift environment has been destroyed. Comment /pr-extend to redeploy it.

hypershell-delivery[bot]

This comment was marked as outdated.

hypershell-delivery[bot]

This comment was marked as outdated.

hypershell-delivery[bot]

This comment was marked as outdated.

hypershell-delivery[bot]

This comment was marked as outdated.

@hypershell-delivery hypershell-delivery Bot removed the amber/changes-requested Amber requested changes on this PR label Oct 7, 2026
user and others added 9 commits October 7, 2026 10:43
Introduces specs/adlc/agents.spec.md, which defines the data model and
requirements for running autonomous AI agents as first-class HyperShell
API resources.

New top-level kinds: AgentRuntime, SandboxTemplate, ProviderSpec,
SecretSource. Workspace-scoped sub-resources: Workspace,
WorkspaceMembership, ProviderBinding, InferenceRoute.

Key design decisions captured in the spec:
- Gateway-agnostic capability model: no OpenShell CLI flags or driver
  names appear in the API; the controller translates them.
- ProviderSpec and SandboxTemplate are reusable across AgentRuntimes.
- SecretSource purpose enum drives env var wiring without operator
  annotation.
- ManifestWork delivers scheduling resources to target clusters via OCM.
- Bootstrap Job provisions gateway-side workspace, members, and providers
  idempotently.
- AgentRuntime owns exactly one Workspace (isolation primitive).

Adds the ADLC section to specs/index.spec.md and registers
adlc/agents.spec.md in the spec registry table.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…emove adlc/

The ADLC spec introduced AgentRuntime, SandboxTemplate, ProviderSpec,
ProviderBinding, InferenceRoute, and SecretSource as a separate specs/adlc/
namespace. These are regular HyperShell API kinds reconciled by the existing
controller - no architectural separation is warranted.

Fold all kinds, ER entities, requirements, and design decisions into the
existing specs/platform/data-model.spec.md alongside Gateway, GatewayNetwork,
and ManagedCluster. Remove specs/adlc/ entirely.

Two architectural corrections applied vs. the original ADLC draft:
- No ManifestWork: the controller applies cluster resources directly,
  same as gateway infrastructure today.
- No bootstrap Job: the controller provisions gateway-side workspace,
  members, and provider bindings via the gateway gRPC API in its normal
  reconcile loop, same as database provisioning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mark both kinds as Slated for Removal in the data model spec:
- GatewayRelease: Gateway image/supervisor_image fields make the release
  indirection layer unnecessary; canary rollout was never adopted.
- GatewayNetwork: The reconciler owns no K8s resources and only validates
  topology fields; real mesh/tunnel provisioning was never defined.

Remove both from the ER diagram. Add deprecation banners to their
requirement sections. Mark API routes, CLI sections, and hsctl apply rows
as [REMOVED]. Add design decision rationale for both removals.

Add 20 RM- gap items to skills/RECONCILE.md covering all 8 implementation
layers (FE -> CLI -> CP -> BE+gRPC -> API+SDK -> DB) in reverse-dependency
removal order.

Extend skills/build/reconcile/SKILL.md with a Kind Removal Wave Pattern
and skills/build/full-stack-pipeline/SKILL.md with a reverse-dependency
execution note, so /reconcile can plan and execute kind deletion the same
way it plans additions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…kinds

Remove GatewayRelease and GatewayNetwork across all implementation layers:
- FE: deleted gateway-release-distribution-aggregation adapter + tests;
  removed GatewayRelease metric from dashboard-control-plane adapter
- CLI: deleted 8 command dirs (create/get/list/delete for both kinds);
  removed URL constants, TUI kind enum entries, release selector from form
- CP: deleted GatewayReleaseReconciler, GatewayNetworkReconciler, WatchGatewayReleases,
  WatchGatewayNetworks; removed release_id propagation from GatewayReconciler;
  watchCount 4->2
- BE: deleted plugins/gatewayReleases and plugins/gatewayNetworks; removed
  release_id/observed_release_id from Gateway model, handler, service, presenters;
  removed GatewayReleaseService+GatewayNetworkService from grpc_authorization.go
- Proto: deleted gateway_releases.proto, gateway_networks.proto and generated stubs
- API: deleted openapi.gatewayReleases.yaml, openapi.gatewayNetworks.yaml;
  removed release_id from openapi.gateways.yaml; cleaned openapi.yaml references
- DB: added drop-table migrations for gateway_releases and gateway_networks tables;
  added drop-column migration for gateways.release_id/observed_release_id

Add 6 new ADLC API kinds (REST layer, no CP watcher/reconciler yet):
- AgentRuntime, SandboxTemplate, ProviderSpec, ProviderBinding,
  InferenceRoute, SecretSource
- OpenAPI specs, models, DAOs, handlers, services, presenters, migrations,
  plugin registrations for all 6 kinds
- Regenerated Go SDK (make generate)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… e2e

- gofmt fixes in reconciler.go, main.go, factory_test.go, inferenceRoutes/model.go
- Regenerate sdk-typescript/src: add AgentRuntime, SandboxTemplate, ProviderSpec,
  ProviderBinding, InferenceRoute, SecretSource; remove GatewayRelease, GatewayNetwork
- e2e area 13 (gateway release promotion): permanently skip since GatewayRelease
  and GatewayNetwork kinds were removed from the data model
- Remove E2E_RELEASE_ID forwarding from e2e-performance.sh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bumps rh-trex-ai to the commit that adds RegisterPrefixedRoutes
(v0.0.0-20261007120905-e2ff9d8640ec / rh-trex-ai#62), then migrates
all six ADLC extension kinds off the shared /v1 surface and onto /ext:

  /api/hypershell/ext/agent_runtimes
  /api/hypershell/ext/inference_routes
  /api/hypershell/ext/provider_bindings
  /api/hypershell/ext/provider_specs
  /api/hypershell/ext/sandbox_templates
  /api/hypershell/ext/secret_sources

Core gateway-management kinds remain on /v1 unchanged. The /ext subrouter
carries the same middleware stack (metrics, auth/authz, DB transaction,
compression) as /v1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ds to /ext

SDK generator now stores and emits full absolute API paths per resource so
each generated client uses the correct URL regardless of which URL segment
the API server mounts the resource under. ADLC extension kinds
(AgentRuntime, InferenceRoute, ProviderBinding, ProviderSpec,
SandboxTemplate, SecretSource) now route to /api/hypershell/ext/*, while
standard kinds continue to use /api/hypershell/v1/*.

Changes:
- sdk-generator/model.go: add AbsoluteCollectionPath field to Resource
- sdk-generator/parser.go: populate AbsoluteCollectionPath from OpenAPI path;
  broaden primaryCollectionViews filter to accept two-segment remainders
  (e.g. ext/agent_runtimes alongside v1/gateways)
- sdk-generator templates (Go, TypeScript, Python): use AbsoluteCollectionPath
  directly; remove APIPrefix injection from base HTTP clients
- components/api-server/Makefile: SDK_API_PREFIX=/api/hypershell (common root)
- openapi specs: change 6 ADLC kind paths from /v1/ to /ext/ in both the
  per-kind yaml files and the root openapi.yaml path keys and $ref pointers
- Regenerate sdk-go and sdk-typescript with updated paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…age allowlist

- Run make generate to regenerate pkg/api/openapi/ after ADLC kinds moved
  from /v1 to /ext in the OpenAPI specs
- Update dependency-age-allowlist.json rh-trex-ai entry from
  v0.0.0-20260925121109-368daa9d29e6 to v0.0.0-20261007120905-e2ff9d8640ec
  (RegisterPrefixedRoutes for configurable URL prefix mounts, PR #62)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…/ext

secret_sources was mounted nested at /agent_runtimes/{agent_runtime_id}/secret_sources
but the spec and SDKs described it as flat. The resource has an explicit
agent_runtime_id field for association and a global unique ID, matching the
shape of the other five ADLC extension kinds. Flatten the route to
/api/hypershell/ext/secret_sources for consistency.

Also updates specs/platform/data-model.spec.md:
- Split API reference into two sections: /v1 (standard) and /ext (ADLC extension)
- Correct all ADLC endpoint paths from /v1 to /ext
- Remove incorrect agent_runtime nesting from provider_bindings and inference_routes rows
- Add secret_sources to the ADLC table
- Fix Create AgentRuntime scenario URL from /v1 to /ext

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@markturansky
markturansky force-pushed the feat/adlc-agent-runtime-spec branch from bff22c1 to 91db7a5 Compare October 7, 2026 14:43

@hypershell-delivery hypershell-delivery Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict

This PR moves the six ADLC extension kinds to a distinct /api/hypershell/ext/ prefix, and the /ext surface is now internally consistent end to end: the source spec, the embedded server OpenAPI, the generated Go client, and both shipped SDKs all agree, and secret_sources is a flat top-level kind. All previously raised Critical and Major concerns are verified fixed against the current code; one pre-existing authz design question (outside this diff) and two cross-PR coordination items are noted below.

Findings

Minor

ADLC kinds fall through to the gateway:creator default authz (pre-existing, not modified here). isAuthorized has no case for agent_runtimes, secret_sources, provider_specs, provider_bindings, inference_routes, or sandbox_templates, so all six resolve to the terminal return hasGatewayCreator(bindings) (components/api-server/pkg/rbac/authorization.go:421), granting any gateway creator full CRUD across the whole /ext surface with no per-resource scoping. This PR does not touch authorization.go, so the behavior is unchanged, but the /ext move keeps the same middleware governing the new surface. Please confirm the coarse model is intended for the ADLC kinds, or file a follow-up to scope them. Confidence: Medium.

Cross-PR coordination

  • An open PR (#445) adds Go/TS SDK columns to the specs/platform/data-model.spec.md client-reference tables and documents GatewayNetworks().* and GatewayReleases().* (and their TypeScript equivalents) as implemented SDK bindings. This PR deletes both kinds outright, including their SDK clients and types (components/sdk-go/client/gateway_network_api.go, components/sdk-go/client/gateway_release_api.go, components/sdk-go/types/gateway_network.go, components/sdk-go/types/gateway_release.go), and reworks the same spec file. The two edits are incompatible: #445 would advertise SDK methods this PR removes, and both rewrite the same Gateway Networks / Gateway Releases rows. Maintainers must choose a merge order and ensure the surviving spec does not document removed SDK methods.

  • An open PR (#466) adds hsctl commands for the six ADLC kinds and hardcodes their URLs under ExtAPIPrefix = "/api/hypershell/ext" in components/cli/pkg/urls/urls.go. That CLI depends on the /ext surface this PR introduces: if #466 merges before this PR, the CLI will call /api/hypershell/ext/* while the server still serves the ADLC kinds under /v1, producing 404s. Maintainers must land this PR first (or merge the two together) so the CLI prefix matches the served routes.

Previous concerns

  • Critical - secret_sources route nested but spec/SDK flat: addressed. The route is now flat (components/api-server/plugins/secretSources/plugin.go:46 -> extRouter.PathPrefix("/secret_sources")), matching the source spec (components/api-server/openapi/openapi.yaml:77), the embedded spec (components/api-server/pkg/api/openapi/api/openapi.yaml:2397), the generated client (components/api-server/pkg/api/openapi/api_default.go:1362), and the Go SDK (components/sdk-go/client/secret_source_api.go:31,47) - all /api/hypershell/ext/secret_sources.
  • Major - nested secret_sources ignored {agent_runtime_id} (IDOR): addressed by flattening. The route no longer carries an {agent_runtime_id} segment; secret_sources is a top-level kind resolved by id, consistent with the other five ADLC kinds. No cross-parent segment remains.
  • Major - data-model spec documented /v1/agent_runtimes: addressed. specs/platform/data-model.spec.md:431 now reads /api/hypershell/ext/agent_runtimes, and the new "ADLC extension kinds - /api/hypershell/ext/" section (:727) lists flat rows for all six kinds.
  • Critical - /v1 vs /ext contract/client mismatch: addressed. The generated client emits /ext (api_default.go:70), matching the routes.
  • Critical - embedded pkg/api/openapi not regenerated for /ext: addressed. The embedded contract now routes all six ADLC kinds to /api/hypershell/ext/* (components/api-server/pkg/api/openapi/api/openapi.yaml:1322,1547,1772,1997,2222,2397), and no /api/hypershell/v1/<adlc-kind> reference remains anywhere in components/, specs/, or scripts/.
  • Minor - ADLC kinds fall through to gateway:creator authz: still present (components/api-server/pkg/rbac/authorization.go:421), pre-existing and outside this diff (see Findings).

Findings Summary (ordered by severity, highest first):

  1. [Minor] ADLC kinds fall through to the gateway:creator default authz; confirm intended (pre-existing, outside this diff) - Authz design (authorization.go L421)

Convention Checklist:

Convention Result
No panic() in production code Pass
Errors wrapped with context Pass
No secrets in logs or responses Pass
Embedded/generated OpenAPI regenerated (not left stale) Pass
OpenAPI client matches served routes Pass
Spec consistent with implementation Pass
Input scoped/validated (nested collection parent) Pass
Conventional commits Pass

@markturansky
markturansky added this pull request to the merge queue Oct 7, 2026
Merged via the queue into main with commit 87b8580 Oct 7, 2026
32 checks passed
@markturansky
markturansky deleted the feat/adlc-agent-runtime-spec branch October 7, 2026 15:46
bsquizz added a commit that referenced this pull request Oct 7, 2026
Resolve conflicts between the user-management feature (gateway access,
roles, role bindings, users) and main's #462 change that moved the ADLC
extension kinds (AgentRuntime, SandboxTemplate, ProviderSpec,
ProviderBinding, InferenceRoute, SecretSource) to the /api/hypershell/ext/
URL prefix.

Hand-merged sources:
- openapi/openapi.yaml: kept HEAD's gateway-access paths; adopted main's
  /api/hypershell/ext/ prefix for the six ADLC extension kinds.
- scripts/sdk-generator/parser.go (projectScopedResource): kept HEAD's
  patch / directory-search / conditional-revoke / TSImports feature block;
  adopted main's absolute-path convention (dropped the *Relative locals,
  directory path now built from the absolute directoryPath).

Regenerated all generated artifacts from the merged spec (make generate,
generate-sdk): pkg/api/openapi, sdk-go, sdk-typescript. Left generate-cli
untouched (its template lags the committed CLI, as in the prior merge).

Verified: sdk-generator go test; go build across sdk-go, cli, api-server;
TS SDK typecheck. Confirmed ext kinds use /ext/ and gateway access uses
absolute /v1 paths in the regenerated SDK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant