Skip to content

feat(agent): add environment agent support, remove direct SP management - #51

Merged
gciavarrini merged 6 commits into
dcm-project:mainfrom
gabriel-farache:feature/env-agent
Aug 19, 2026
Merged

feat(agent): add environment agent support, remove direct SP management#51
gciavarrini merged 6 commits into
dcm-project:mainfrom
gabriel-farache:feature/env-agent

Conversation

@gciavarrini

@gciavarrini gciavarrini commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

PR #37 was closed by mistake and cannot be reopened after a force-push/recreate on the fork branch.

gabriel-farache and others added 5 commits August 12, 2026 15:50
Introduce agent-based resource provisioning via NATS and remove all direct
Service Provider (SP) management, completing the transition to an
agent-only architecture. Each resource in a run is now routed to an agent
(policy.SelectedAgent) rather than a provider, with per-resource SPRM
provisioning using AgentName.

- Agent domain (internal/agent/): store, service, HTTP handler (split into
  handler/convert/errors, matching the SP pattern), health monitor,
  OpenAPI spec and generated server/client/types
- NATS integration (internal/sp/messaging/, internal/sp/consumer/,
  internal/sp/pending/): CloudEvents publish/consume and sweep-driven
  pending/queued retries and self-heal, including a CAS fix for a race
  that let two concurrent healers reassign the same instance to
  different agents, and proactive reassignment of run-siblings stuck on
  an excluded agent
- Policy: ServiceTypes and Cost threaded into agent evaluation so Rego
  can see agent capability, with a hard capability pre-filter and
  explicit rejection when no capable or all-excluded agents remain
  (previously silent/fail-open)
- Placement: agent-aware routing in CreateRun/RehydrateResource/
  ReEvaluateWithExclude; ProviderName replaced by AgentName across the
  store model, DTO, and ListRun filter; fail closed instead of open when
  listing ready agents errors
- SP resource manager: CreateInstance publishes to NATS instead of
  calling provider HTTP, with AgentName on ServiceTypeInstance and a
  matching agent_name filter on ListInstances
- Removed all provider-specific code (internal/sp/*/provider,
  api/sp/*/provider, pkg/sp/client/provider)
- Subsystem coverage for NATS response events, self-heal sweep
  re-routing, and sibling reassignment during self-heal (PR dcm-project#37 review
  thread r3761347505)

Assisted by: Cursor - Sonnet 5

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: gabriel-farache <gfarache@redhat.com>
Resource lifecycle events (create/queue/cancel/delete) had audit gaps:
Publisher never logged publish outcomes, and several response-consumer
and sweep transitions were silent on success, so a resource's history
couldn't be reconstructed from logs alone. Add centralized publish
logging in Publisher.publish, success-path transition logs across
response_consumer.go and sweep.go, and unify resource_id/ce_type log
keys to instance_id/event_type for consistent querying.

Validated with two rounds of independent multi-model review (Opus,
Grok, Gemini, Codex) across audit-completeness and code-quality/
operational-safety angles. Round findings closed: missing fields on
failure/stale paths, a data race in the test log-capture harness
(confirmed via -race), and incomplete test assertions.

Assisted by: Cursor - Sonnet 4.5

Signed-off-by: gabriel-farache <gfarache@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
MarkDeletionFailed now skips rows already DELETED so a late
cleanup timeout cannot overwrite a completed agent ack.

Assisted-By: Claude (Anthropic)
Signed-off-by: Gloria Ciavarrini <gciavarrini@redhat.com>
Unique-constraint hits on Create are no longer retried and surface
as 409 instead of a generic 500 after backoff.

Assisted-By: Claude (Anthropic)
Signed-off-by: Gloria Ciavarrini <gciavarrini@redhat.com>
Put back entry/list Debug and resolve-ID Warn/Error logs dropped
in the agent rewrite.

Assisted-By: Claude (Anthropic)
Signed-off-by: Gloria Ciavarrini <gciavarrini@redhat.com>
@gciavarrini
gciavarrini requested a review from a team as a code owner August 14, 2026 14:23
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add environment agent API + NATS provisioning; remove direct SP management

✨ Enhancement 🐞 Bug fix 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Introduce Agent domain + HTTP API for agent registration, listing, and heartbeats.
• Route placement decisions to agents and dispatch provisioning via NATS CloudEvents.
• Add sweep-driven self-heal/retry loops and harden concurrency with CAS-based transitions.
Diagram

graph TD
  CP["Control Plane"] --> AgentAPI["Agent HTTP API"] --> AgentDB[("Agent Store")]
  CP --> Placement["Placement Service"] --> Policy["Policy/OPA"]
  Placement --> SPRM["SP Resource Manager"] --> NATS[("NATS JetStream")]
  NATS --> AgentExt{{"Env Agent"}} --> NATS
  Placement --> AgentDB
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep provider API as a compatibility facade
  • ➕ Reduces blast radius for existing clients that still call /providers
  • ➕ Allows staged migration (dual-write/dual-read) instead of flag day
  • ➖ Maintains two control paths and complicates correctness (provider vs agent source of truth)
  • ➖ Delays removing provider-specific schema/health logic
2. Use request-reply NATS instead of work-queue + sweeps
  • ➕ Potentially simpler mental model for a single resource operation
  • ➕ May reduce need for periodic sweeps for some timeout cases
  • ➖ Harder to handle long-running provisioning and offline agents
  • ➖ Less resilient to control-plane restarts without persisted state + retry orchestration
3. Adopt a CloudEvents SDK and schema-first validation
  • ➕ Standardizes CE envelope handling and validation
  • ➕ Reduces bespoke parsing logic in consumers/publishers
  • ➖ Extra dependency and potential mismatch with existing agent wire format
  • ➖ PR already defines a clear minimal contract; switching now increases churn

Recommendation: The agent-only architecture with JetStream work-queues + explicit DB-backed state (pending/queued/deleting) is the most robust foundation for asynchronous provisioning and self-heal. If backwards compatibility is needed, a thin provider facade could be added later, but keeping it out of this PR avoids long-term dual-path complexity.

Files changed (108) +12410 / -2416

Enhancement (41) +5257 / -600
openapi.yamlAdd Agent API OpenAPI spec +374/-0

Add Agent API OpenAPI spec

• Introduces a new v1alpha1 Agent API contract for registering agents, listing agents, and posting heartbeats with health status semantics.

api/agent/v1alpha1/openapi.yaml

spec.gen.goGenerated Agent API spec loader +148/-0

Generated Agent API spec loader

• Adds generated code to embed/load the Agent OpenAPI spec at runtime for validation and tooling.

api/agent/v1alpha1/spec.gen.go

types.gen.goGenerated Agent API types +230/-0

Generated Agent API types

• Adds generated Go types for Agent resources, request/response payloads, and enums (health status, cost).

api/agent/v1alpha1/types.gen.go

openapi.yamlMake service instances agent-aware +26/-13

Make service instances agent-aware

• Updates Resource Manager API filtering to use service_type + agent_name and documents new error cases and schema fields (agent_name, deletion semantics).

api/sp/v1alpha1/resource_manager/openapi.yaml

spec.gen.goRegenerate Resource Manager server spec bindings +44/-43

Regenerate Resource Manager server spec bindings

• Regenerates Resource Manager OpenAPI bindings to reflect agent_name query params and updated schema/response codes.

api/sp/v1alpha1/resource_manager/spec.gen.go

types.gen.goRegenerate Resource Manager types for agent fields +9/-15

Regenerate Resource Manager types for agent fields

• Updates generated types to include agent_name and revised deletion status enum.

api/sp/v1alpha1/resource_manager/types.gen.go

server.gen.goGenerated Agent API server implementation +1000/-0

Generated Agent API server implementation

• Adds generated chi-based server scaffolding for Agent API endpoints and request/response typing.

internal/agent/api/server/server.gen.go

convert.goAgent API model↔DTO conversions +40/-0

Agent API model↔DTO conversions

• Implements conversions between internal agent models and v1alpha1 API types.

internal/agent/handlers/v1alpha1/convert.go

errors.goAgent API error mapping +94/-0

Agent API error mapping

• Defines problem+json error helpers and maps service/store errors to HTTP responses for the Agent API.

internal/agent/handlers/v1alpha1/errors.go

handler.goAgent API HTTP handlers +93/-0

Agent API HTTP handlers

• Implements Agent API endpoint handlers for register/update, get, list, and heartbeat flows.

internal/agent/handlers/v1alpha1/handler.go

monitor.goHeartbeat-based agent health monitor +67/-0

Heartbeat-based agent health monitor

• Introduces a periodic sweep that atomically marks stale agents unavailable based on heartbeat timeout.

internal/agent/healthcheck/monitor.go

agent.goAgent service (register/list/heartbeat) +174/-0

Agent service (register/list/heartbeat)

• Adds business logic for idempotent registration, listing with pagination, and monotonic heartbeat updates that compute health status from consumer lag.

internal/agent/service/agent.go

errors.goAgent domain error types +59/-0

Agent domain error types

• Defines typed service errors (validation, conflict, not found) for consistent handler mapping.

internal/agent/service/errors.go

agent.goGORM agent store with paging + CAS updates +251/-0

GORM agent store with paging + CAS updates

• Adds persistent agent store with unique constraint handling, paginated listing, ready-agent queries, monotonic heartbeat updates, and stale-agent marking.

internal/agent/store/agent/agent.go

pagination.goAgent pagination token helpers +42/-0

Agent pagination token helpers

• Implements encode/decode of opaque page tokens for Agent list APIs.

internal/agent/store/agent/pagination.go

agent.goAgent DB model +42/-0

Agent DB model

• Defines the Agent database model (name/topic uniqueness, service types, cost, health status, heartbeat timestamps).

internal/agent/store/model/agent.go

db.goWire agent models into DB migration +2/-1

Wire agent models into DB migration

• Extends DB initialization/migration wiring to include agent domain storage changes.

internal/app/db.go

openapi.goAdd Agent API OpenAPI validation; remove provider validation +17/-20

Add Agent API OpenAPI validation; remove provider validation

• Loads and routes OpenAPI request validation for /agents and removes provider OpenAPI validation middleware.

internal/app/openapi.go

run.goMonolith wiring for agents + NATS workers + sweeps +88/-57

Monolith wiring for agents + NATS workers + sweeps

• Wires Agent store/service/health monitor, initializes JetStream publisher and response consumer, and starts pending/queued sweep loops for self-healing.

internal/app/run.go

service_client.goPlacement adapter to list ready agents +39/-0

Placement adapter to list ready agents

• Introduces an in-process client adapter that exposes ListReadyAgents for policy evaluation without depending on full agent store interfaces.

internal/placement/agent/service_client.go

types.goPlacement agent info types +20/-0

Placement agent info types

• Defines lightweight agent info structures (name, environment, service types, cost) used by placement and policy layers.

internal/placement/agent/types.go

service_client.goPolicy client supports agent inputs +10/-3

Policy client supports agent inputs

• Extends placement→policy client request types to include available agents and excluded agents for re-evaluation flows.

internal/placement/policy/service_client.go

types.goPolicy request/response uses SelectedAgent +17/-4

Policy request/response uses SelectedAgent

• Updates placement policy DTOs to use SelectedAgent (replacing SelectedProvider) and to carry agent lists/exclusions.

internal/placement/policy/types.go

placement.goAgent-aware placement + self-heal re-evaluation +225/-26

Agent-aware placement + self-heal re-evaluation

• Routes CreateRun/RehydrateResource via SelectedAgent, lists ready agents for policy evaluation, and adds ReEvaluateWithExclude with sibling reassignment and CAS-safe SPRM reassign calls.

internal/placement/service/placement.go

service_client.goSPRM client uses AgentName and supports reassignment +27/-5

SPRM client uses AgentName and supports reassignment

• Updates placement→SPRM client to pass AgentName for provisioning and to support ReassignResource for self-healing flows.

internal/placement/sprm/service_client.go

types.goSPRM client request types updated for agents +13/-3

SPRM client request types updated for agents

• Replaces provider-oriented request fields with agent-oriented fields (AgentName, expected agent for CAS).

internal/placement/sprm/types.go

resource.goResource store filters + updates by AgentName +19/-5

Resource store filters + updates by AgentName

• Updates resource listing filters to use agent_name and adds UpdateAgentName for observability after self-heal reassignment.

internal/placement/store/resource.go

resource.goPlacement API resource includes agent_name +1/-1

Placement API resource includes agent_name

• Updates placement API DTOs to expose agent_name instead of provider_name.

internal/placement/types/resource.go

constraints.goAdd accumulated agent constraints + validation +125/-94

Add accumulated agent constraints + validation

• Replaces provider constraints with agent constraints, including membership checks against available agents and environment constraint enforcement.

internal/policy/service/constraints.go

evaluation.goPolicy evaluation selects agents (not providers) +179/-50

Policy evaluation selects agents (not providers)

• Updates evaluation flow to carry SelectedAgent, inject available_agents/exclude_agents into OPA input, and enforce explicit rejection on empty post-exclusion lists.

internal/policy/service/evaluation.go

server.gen.goUpdate generated SP Resource Manager server surface +45/-23

Update generated SP Resource Manager server surface

• Regenerates server bindings to reflect agent_name query filter and updated schemas/error responses.

internal/sp/api/resource_manager/server.gen.go

scheduler.goCleanup scheduler publishes agent deletes + audit give-up +88/-38

Cleanup scheduler publishes agent deletes + audit give-up

• Refactors cleanup to be agent-only: publishes delete requests to agents, bounds cycles by timeout, increments retry counts consistently, and logs audited give-up when agent/publisher is unavailable.

internal/sp/cleanup/scheduler.go

response_consumer.goAdd JetStream consumer for agent response CloudEvents +374/-0

Add JetStream consumer for agent response CloudEvents

• Introduces a durable JetStream consumer that parses agent response CloudEvents and applies CAS-guarded state transitions gated by agent_name.

internal/sp/consumer/response_consumer.go

errors.goMap new agent/NATS errors to HTTP status codes +20/-7

Map new agent/NATS errors to HTTP status codes

• Extends handler error mapping for new provisioning/unavailable cases (e.g., cannot publish to agent).

internal/sp/handlers/resource_manager/errors.go

publisher.goJetStream CloudEvent publisher with bounded retries + dedup +104/-0

JetStream CloudEvent publisher with bounded retries + dedup

• Adds a publisher that wraps agent requests in a CloudEvent envelope, retries publish with exponential backoff, and uses Msg-Id deduplication.

internal/sp/messaging/publisher.go

types.goDefine request/response CloudEvent types + payloads +52/-0

Define request/response CloudEvent types + payloads

• Introduces constants for agent request/response event types, stream/subject names, and payload structures (create/delete/cancel).

internal/sp/messaging/types.go

errors.goSP service error surface updated for agent-only provisioning +16/-8

SP service error surface updated for agent-only provisioning

• Adds/adjusts error types to represent agent/NATS unavailability and provisioning publish failures.

internal/sp/service/errors.go

service_type_instance.goDispatch create/delete/reassign via agents over NATS +229/-175

Dispatch create/delete/reassign via agents over NATS

• Replaces provider HTTP calls with agent validation + JetStream publishes for create/delete/cancel and adds ReassignAgent for self-healing with CAS safety.

internal/sp/service/resource_manager/service_type_instance.go

service_type_instance.goServiceTypeInstance schema: add agent_name + pending_started_at + indexes +23/-5

ServiceTypeInstance schema: add agent_name + pending_started_at + indexes

• Removes provider_name, adds agent_name and pending_started_at for sweep timeouts, and introduces indexes for sweep and deletion hot paths.

internal/sp/store/model/service_type_instance.go

client.gen.goGenerated Agent API client +811/-0

Generated Agent API client

• Adds generated Go client for calling Agent API endpoints (list/get/register/heartbeat).

pkg/agent/client/client.gen.go

client.gen.goRegenerate SP Resource Manager client for agent fields +20/-4

Regenerate SP Resource Manager client for agent fields

• Updates generated client to support agent_name filtering and updated schema/errors.

pkg/sp/client/resource_manager/client.gen.go

Bug fix (5) +667 / -98
errors.goPlacement errors updated for agent routing failures +25/-8

Placement errors updated for agent routing failures

• Adds/adjusts placement error handling to cover agent listing failures and stricter policy failure cases (no capable/all excluded).

internal/placement/service/errors.go

evaluation.goOPA evaluation includes available/excluded agent metadata +31/-23

OPA evaluation includes available/excluded agent metadata

• Threads ServiceTypes and Cost into policy evaluation inputs, pre-filters by capability, and explicitly errors when no capable or all-excluded agents remain.

internal/policy/opa/evaluation.go

errors.goPolicy service errors for agent unavailability +28/-3

Policy service errors for agent unavailability

• Adds/updates error types surfaced when no capable agents exist or all agents are excluded.

internal/policy/service/errors.go

sweep.goAdd pending/queued timeout sweeper with self-heal +359/-0

Add pending/queued timeout sweeper with self-heal

• Implements periodic sweeps that claim timed-out instances via CAS, re-evaluate placement to a new agent, notify cancel best-effort, and mark failed only after retries are exhausted.

internal/sp/pending/sweep.go

service_instance.goCAS-safe status transitions + reassignment primitives +224/-64

CAS-safe status transitions + reassignment primitives

• Adds UpdateStatusFrom/MarkQueued/ReassignAndReset plus agent-gated delete completion APIs; also fixes a retry backoff data race by generating retry options per call.

internal/sp/store/resource_manager/service_instance.go

Refactor (10) +80 / -38
local_client.goAgent-aware catalog placement client usage +16/-2

Agent-aware catalog placement client usage

• Updates local placement client interactions to match agent-based placement/DTO changes.

internal/catalog/placement/local_client.go

catalog_item_instance.goPropagate agent placement fields in catalog instance logic +4/-1

Propagate agent placement fields in catalog instance logic

• Adapts catalog instance handling to align with agent-based resource placement metadata.

internal/catalog/service/catalog_item_instance.go

convert.goPlacement conversions updated for AgentName +1/-1

Placement conversions updated for AgentName

• Updates conversion logic to map AgentName through placement service and API models.

internal/placement/service/convert.go

resource.goReplace ProviderName with AgentName in resource model +9/-1

Replace ProviderName with AgentName in resource model

• Updates placement resource DB model to store AgentName as a soft reference (no FK) and removes ProviderName.

internal/placement/store/model/resource.go

consumer.goAdjust SP consumer integration for agent-only flows +9/-2

Adjust SP consumer integration for agent-only flows

• Updates SP consumer wiring to align with agent-driven provisioning and status handling.

internal/sp/consumer/consumer.go

convert.goExpose agent_name and updated filters in handlers +9/-10

Expose agent_name and updated filters in handlers

• Updates HTTP handler conversions to match agent_name fields and new list filter parameters.

internal/sp/handlers/resource_manager/convert.go

handler.goResource manager handler updates for agent routing +3/-7

Resource manager handler updates for agent routing

• Adjusts handler behavior to use agent-aware instance service methods and query parameters.

internal/sp/handlers/resource_manager/handler.go

convert.goService instance API conversion uses agent_name +7/-13

Service instance API conversion uses agent_name

• Updates model/API conversions to include agent_name and reflect removal of provider_name.

internal/sp/service/resource_manager/convert.go

db.goAlign SP store DB wiring with new models +1/-1

Align SP store DB wiring with new models

• Updates store initialization/migrations to match new ServiceTypeInstance schema fields and indices.

internal/sp/store/db.go

status.goCentralize instance status constants +21/-0

Centralize instance status constants

• Adds status constants to reduce drift across sweeps, consumers, and service logic.

internal/sp/store/model/status.go

Tests (40) +6334 / -1623
errors_test.goAgent API error mapping tests +112/-0

Agent API error mapping tests

• Adds unit tests for Agent API error translation and response formatting.

internal/agent/handlers/v1alpha1/errors_test.go

handler_suite_test.goAgent handler test suite wiring +3/-3

Agent handler test suite wiring

• Updates/introduces Ginkgo suite setup for handler tests.

internal/agent/handlers/v1alpha1/handler_suite_test.go

handler_test.goAgent handler behavior tests +214/-0

Agent handler behavior tests

• Adds request/response tests validating handler behavior across success paths and validation/conflict cases.

internal/agent/handlers/v1alpha1/handler_test.go

healthcheck_suite_test.goAgent healthcheck suite wiring +2/-2

Agent healthcheck suite wiring

• Adds/updates Ginkgo suite scaffolding for agent health monitoring tests.

internal/agent/healthcheck/healthcheck_suite_test.go

monitor_test.goAgent health monitor tests +144/-0

Agent health monitor tests

• Adds tests for stale-agent detection and ensuring sweeps don’t clobber newer heartbeats.

internal/agent/healthcheck/monitor_test.go

agent_suite_test.goAgent service test suite +13/-0

Agent service test suite

• Adds Ginkgo suite setup for agent service tests.

internal/agent/service/agent_suite_test.go

agent_test.goAgent service tests +253/-0

Agent service tests

• Covers registration conflicts, list pagination/filtering, and heartbeat monotonicity/health status transitions.

internal/agent/service/agent_test.go

agent_suite_test.goAgent store suite wiring +3/-3

Agent store suite wiring

• Adds/updates Ginkgo suite setup for agent store tests.

internal/agent/store/agent/agent_suite_test.go

agent_test.goAgent store persistence tests +398/-0

Agent store persistence tests

• Validates unique constraints, pagination tokens, ready listing, heartbeat CAS behavior, and stale marking.

internal/agent/store/agent/agent_test.go

openapi_validation_test.goRemove provider OpenAPI validation coverage +0/-6

Remove provider OpenAPI validation coverage

• Adjusts validation tests to reflect removal of provider endpoints from the OpenAPI validation layer.

internal/app/openapi_validation_test.go

catalog_item_instance_test.goCatalog instance tests for agent routing +45/-0

Catalog instance tests for agent routing

• Adds/updates tests validating catalog instance behavior with agent-based placement results.

internal/catalog/service/catalog_item_instance_test.go

service_client_test.goPlacement agent client tests +63/-0

Placement agent client tests

• Adds tests covering ready agent listing and cost/service-type mapping.

internal/placement/agent/service_client_test.go

service_client_test.goPolicy client tests for agent-aware evaluation +155/-0

Policy client tests for agent-aware evaluation

• Adds coverage ensuring available/excluded agent fields are propagated into policy evaluation requests.

internal/placement/policy/service_client_test.go

placement_test.goPlacement tests for agent selection + re-evaluation +539/-50

Placement tests for agent selection + re-evaluation

• Expands test coverage for agent-aware placement, exclusion-based re-evaluation, and sibling reassignment behavior.

internal/placement/service/placement_test.go

service_client_test.goSPRM client tests for agent routing +89/-0

SPRM client tests for agent routing

• Adds tests ensuring AgentName is correctly passed and reassignment calls are wired.

internal/placement/sprm/service_client_test.go

resource_test.goResource store tests for agent fields +71/-41

Resource store tests for agent fields

• Updates tests to validate listing/filtering and UpdateAgentName behavior with agent_name semantics.

internal/placement/store/resource_test.go

evaluation_test.goUpdate OPA evaluation tests for agent inputs +11/-11

Update OPA evaluation tests for agent inputs

• Adjusts tests to validate selected agent behavior and new error conditions for exclusions/capability.

internal/policy/opa/evaluation_test.go

agent_constraints_test.goAdd agent constraint behavior tests +113/-0

Add agent constraint behavior tests

• Adds tests covering allow-list/pattern/environment constraints for agent selection and validation.

internal/policy/service/agent_constraints_test.go

constraints_test.goConstraint tests for agent validation +0/-80

Constraint tests for agent validation

• Adds new tests validating agent constraint merging and validation behavior.

internal/policy/service/constraints_test.go

evaluation_test.goEvaluation tests for agent selection semantics +467/-13

Evaluation tests for agent selection semantics

• Updates and expands evaluation tests to cover agent selection, exclusion fail-closed behavior, and capability prefiltering.

internal/policy/service/evaluation_test.go

scheduler_test.goCleanup tests updated for agent-only deletion +116/-63

Cleanup tests updated for agent-only deletion

• Replaces provider HTTP server tests with agent-focused cases using a stub JetStream publisher and agent store fixtures.

internal/sp/cleanup/scheduler_test.go

consumer_test.goUpdate consumer tests for new wiring +35/-6

Update consumer tests for new wiring

• Adjusts SP consumer tests to reflect updated construction and agent-only behavior.

internal/sp/consumer/consumer_test.go

response_consumer_test.goResponse consumer tests (status transitions + deletion/cancel flows) +767/-0

Response consumer tests (status transitions + deletion/cancel flows)

• Adds extensive tests covering CE parsing, status transitions, queued semantics, deletion acknowledgement handling, and cancel-rejected retries.

internal/sp/consumer/response_consumer_test.go

errors_test.goHandler error mapping tests for new cases +29/-0

Handler error mapping tests for new cases

• Adds tests for updated problem+json mappings introduced by agent/NATS flows.

internal/sp/handlers/resource_manager/errors_test.go

handler_test.goUpdate resource manager handler tests +69/-183

Update resource manager handler tests

• Reworks tests to reflect new agent_name filters and agent-routed create/delete behavior.

internal/sp/handlers/resource_manager/handler_test.go

messaging_suite_test.goMessaging package test suite +3/-3

Messaging package test suite

• Adds Ginkgo suite scaffolding for messaging tests.

internal/sp/messaging/messaging_suite_test.go

publisher_test.goPublisher tests (envelope + retry/dedup behavior) +331/-0

Publisher tests (envelope + retry/dedup behavior)

• Adds tests validating envelope formation, retry behavior, and failure handling in the messaging publisher.

internal/sp/messaging/publisher_test.go

pending_suite_test.goPending sweep test suite scaffolding +13/-0

Pending sweep test suite scaffolding

• Adds Ginkgo suite wiring for pending/queued sweep tests.

internal/sp/pending/pending_suite_test.go

sweep_test.goSweep tests (CAS races, retries, queued cancel+heal) +565/-0

Sweep tests (CAS races, retries, queued cancel+heal)

• Adds comprehensive tests for pending/queued sweep behaviors including race prevention, retry accounting, and fallback transitions.

internal/sp/pending/sweep_test.go

service_type_instance_test.goInstance service tests for NATS dispatch + validation +380/-445

Instance service tests for NATS dispatch + validation

• Adds tests for agent validation, publish failures, rollback behavior, reassignment CAS expectations, and delete semantics.

internal/sp/service/resource_manager/service_type_instance_test.go

service_instance_test.goStore tests for agent fields + conflict handling +452/-194

Store tests for agent fields + conflict handling

• Updates tests for new schema, adds duplicate-ID conflict behavior, and removes provider-name filtering expectations.

internal/sp/store/resource_manager/service_instance_test.go

docker-compose.yamlSubsystem test wiring for agent-based flows +10/-0

Subsystem test wiring for agent-based flows

• Updates subsystem docker-compose to support agent-based provisioning and response event simulation.

test/subsystem/sp/docker-compose.yaml

response_events_test.goSubsystem tests for agent response event handling +95/-0

Subsystem tests for agent response event handling

• Adds integration tests validating that agent-emitted CloudEvents drive correct instance state transitions.

test/subsystem/sp/response_events_test.go

self_heal_test.goSubsystem tests for sweep-driven self-healing +295/-0

Subsystem tests for sweep-driven self-healing

• Adds integration coverage for pending/queued timeouts triggering reassignment and preventing double-heal races.

test/subsystem/sp/self_heal_test.go

service_instance_test.goSubsystem tests updated for agent-only instance lifecycle +44/-368

Subsystem tests updated for agent-only instance lifecycle

• Reworks service instance integration tests to use agent routing semantics and revised delete behavior.

test/subsystem/sp/service_instance_test.go

setup_test.goSubsystem setup for agents + policies +320/-152

Subsystem setup for agents + policies

• Extends subsystem test setup to register multiple agents, configure selecting policies, and bootstrap NATS streams/consumers.

test/subsystem/sp/setup_test.go

suite_test.goSubsystem suite initialization for agent architecture +61/-0

Subsystem suite initialization for agent architecture

• Adds/updates the subsystem suite bootstrap reflecting the new agent-only provisioning architecture.

test/subsystem/sp/suite_test.go

agent_selecting_policy.regoTest policy selecting a single agent +8/-0

Test policy selecting a single agent

• Adds Rego policy fixture that selects an agent based on available agent metadata.

test/subsystem/sp/testdata/agent_selecting_policy.rego

three_agent_selecting_policy.regoTest policy selecting among three agents +27/-0

Test policy selecting among three agents

• Adds Rego fixture to exercise ranking/selection across multiple agents with exclusions/capabilities.

test/subsystem/sp/testdata/three_agent_selecting_policy.rego

two_agent_selecting_policy.regoTest policy selecting among two agents +19/-0

Test policy selecting among two agents

• Adds Rego fixture to validate selection and fallback behavior when an agent is excluded or incapable.

test/subsystem/sp/testdata/two_agent_selecting_policy.rego

Other (12) +72 / -57
.gitignoreIgnore generated agent/SP artifacts +2/-0

Ignore generated agent/SP artifacts

• Updates ignore rules to account for newly generated agent-related outputs and build artifacts.

.gitignore

MakefileWire agent make targets +1/-0

Wire agent make targets

• Adds/updates top-level make integration to include agent-specific build/generation steps.

Makefile

spec.gen.cfgConfigure Agent API spec generation +1/-1

Configure Agent API spec generation

• Adds generator configuration for producing Go server/client bindings from the Agent OpenAPI spec.

api/agent/v1alpha1/spec.gen.cfg

types.gen.cfgConfigure Agent API type generation +1/-1

Configure Agent API type generation

• Adjusts generator configuration for Agent API Go types.

api/agent/v1alpha1/types.gen.cfg

go.modUpdate dependencies for NATS/JetStream + backoff +1/-2

Update dependencies for NATS/JetStream + backoff

• Adjusts module dependencies to support JetStream messaging, CloudEvent publication retries, and related refactors.

go.mod

go.sumRefresh dependency checksums +0/-2

Refresh dependency checksums

• Updates go.sum to match dependency graph changes.

go.sum

server.gen.cfgConfigure generated Agent API server +1/-1

Configure generated Agent API server

• Adds config for generating the internal Agent API server stubs.

internal/agent/api/server/server.gen.cfg

config.goAdd agent runtime config knobs +12/-0

Add agent runtime config knobs

• Introduces AgentConfig for heartbeat timeout, consumer lag thresholds, sweep intervals, timeouts, and response consumer retry settings.

internal/app/config.go

config.goRemove SP healthcheck config (provider-era) +4/-13

Remove SP healthcheck config (provider-era)

• Simplifies SP config by removing provider healthcheck configuration now that direct provider management is removed.

internal/sp/config/config.go

agent.mkAdd agent codegen/build make rules +37/-0

Add agent codegen/build make rules

• Introduces make targets for agent OpenAPI generation and related build steps.

make/agent.mk

sp.mkRemove provider-era make rules; keep SP agent-only targets +4/-37

Remove provider-era make rules; keep SP agent-only targets

• Cleans up SP make rules by removing provider artifacts and retaining only agent-compatible generation steps.

make/sp.mk

client.gen.cfgConfigure generated Agent API client +8/-0

Configure generated Agent API client

• Adds generator configuration for the public Go Agent API client package.

pkg/agent/client/client.gen.cfg

@qodo-code-review

qodo-code-review Bot commented Aug 14, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. DeletionStatus schema mismatch ✓ Resolved 🐞 Bug ≡ Correctness
Description
The SP store now sets deletion_status to "DELETED" when deletion completes, but the published
OpenAPI enum and generated ServiceTypeInstanceDeletionStatus.Valid() only allow SCHEDULED/FAILED.
This can expose undocumented values to API clients (e.g., with show_deleted=true) and break enum
validation or strict client code.
Code

internal/sp/store/resource_manager/service_instance.go[R319-321]

+	DeletionStatusScheduled = "SCHEDULED"
+	DeletionStatusFailed    = "FAILED"
+	DeletionStatusDeleted   = "DELETED"
Evidence
The store writes "DELETED" into deletion_status, and the API conversion returns that value, but
the OpenAPI schema and generated enum validation do not permit "DELETED".

internal/sp/store/resource_manager/service_instance.go[318-322]
internal/sp/store/resource_manager/service_instance.go[396-407]
internal/sp/service/resource_manager/convert.go[11-31]
api/sp/v1alpha1/resource_manager/openapi.yaml[342-350]
internal/sp/api/resource_manager/server.gen.go[23-39]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The implementation persists and can return `deletion_status="DELETED"`, but the OpenAPI schema and generated enum validation do not include `DELETED`. This is an API contract inconsistency.

## Issue Context
- `MarkDeletionComplete*` writes `DELETED` into the database.
- `ModelToAPI` serializes `DeletionStatus` directly from the stored string.
- OpenAPI restricts `deletion_status` to `[SCHEDULED, FAILED]`, and generated enum validation matches that restriction.

## Fix Focus Areas
- Update OpenAPI enum to include `DELETED` (and regenerate server/client types), **or** stop emitting/storing `DELETED` (e.g., clear `deletion_status` on completion or hard-delete instead).

- internal/sp/store/resource_manager/service_instance.go[318-407]
- api/sp/v1alpha1/resource_manager/openapi.yaml[342-350]
- internal/sp/api/resource_manager/server.gen.go[23-39]
- internal/sp/service/resource_manager/convert.go[11-31]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. CreateInstance always fails ✗ Dismissed 🐞 Bug ≡ Correctness
Description
SPRM's HTTP CreateInstance handler calls InstanceService.CreateInstance with agentName="", which is
rejected as a validation error and mapped to HTTP 400. This makes POST /service-type-instances
unusable via the REST API despite the operation remaining in the OpenAPI spec.
Code

internal/sp/handlers/resource_manager/handler.go[64]

+	result, err := h.instanceService.CreateInstance(ctx, instance, request.Params.Id, "")
Evidence
The handler hardcodes an empty agent name, while the service layer explicitly rejects empty agent
names and the handler maps that validation error to HTTP 400, making success impossible for this
endpoint.

internal/sp/handlers/resource_manager/handler.go[57-71]
internal/sp/service/resource_manager/service_type_instance.go[39-62]
internal/sp/handlers/resource_manager/errors.go[54-74]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`POST /service-type-instances` is effectively broken: the HTTP handler always passes an empty `agentName` to the service layer, which rejects it, so callers can never successfully create an instance through this REST endpoint.

## Issue Context
- `InstanceService.CreateInstance` now requires a non-empty agent name to avoid orphaned pending instances.
- The REST handler currently has no way to supply an agent name and hardcodes `""`.

## Fix Focus Areas
Choose one of these consistent fixes (preferred: remove unsupported endpoint if creation is only supported via placement flow):
1) **Remove** the `POST /service-type-instances` operation from the OpenAPI spec and generated server/client, and delete/disable the handler route.
2) **Or** extend the API contract to accept `agent_name` (query param or body field), validate it, and pass it through to `InstanceService.CreateInstance`.

- internal/sp/handlers/resource_manager/handler.go[57-71]
- internal/sp/service/resource_manager/service_type_instance.go[39-62]
- internal/sp/handlers/resource_manager/errors.go[54-74]
- api/sp/v1alpha1/resource_manager/openapi.yaml[30-160]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can show, collapse, or hide each part of a finding: code, evidence, and all

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread internal/sp/handlers/resource_manager/handler.go
Comment thread internal/sp/store/resource_manager/service_instance.go
@gciavarrini

Copy link
Copy Markdown
Contributor Author

Let's try to reopen #37

@gciavarrini

Copy link
Copy Markdown
Contributor Author

Can't reopen #37

@gciavarrini gciavarrini reopened this Aug 14, 2026
Comment thread internal/sp/handlers/resource_manager/handler.go
Comment thread api/sp/v1alpha1/resource_manager/openapi.yaml Outdated

@jordigilh jordigilh 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.

lgtm

Align OpenAPI with MarkDeletionComplete and cover
show_deleted list/get for DELETED and FAILED.

Assisted-By: Claude (Anthropic)
Signed-off-by: Gloria Ciavarrini <gciavarrini@redhat.com>

@chadcrum chadcrum left a comment

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.

LGTM!

@gciavarrini
gciavarrini merged commit 35c0e8f into dcm-project:main Aug 19, 2026
7 checks passed
jenniferubah pushed a commit that referenced this pull request Aug 19, 2026
## Summary

- PR #51 removed the `/providers` API (replaced by agent management).
TC-30
(`auth_disabled_test.go`) used `/providers` as a target endpoint — now
uses
  `/service-types` which is still available in the catalog API.

Fixes the `catalog-subsystem` CI failure blocking all open PRs on
`main`.

## Test plan

- `make catalog-subsystem-test` — 41/41 specs passed locally

Made with [Cursor](https://cursor.com)

Signed-off-by: Vladislav Kolodny <vkolodny@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
vkolodny added a commit to dcm-project/utilities that referenced this pull request Aug 21, 2026
…talog-items (#38)

## Summary


[control-plane#51](dcm-project/control-plane#51)
removed
the `/providers` endpoint entirely (replaced by agent-based architecture
over NATS).

- **TC-08**: rewrite from "Provider CRUD" to "Agent CRUD" (`POST/GET
/agents`)
- **TC-02, TC-34**: replace provider create/delete with agent
registration
- **All other TCs**: `/providers` → `/catalog-items` as generic
protected endpoint
- **TC-37/38**: clarify step titles for SP-as-agent context
- Add migration note documenting the API change

No functional test coverage lost — agent DELETE doesn't exist by design
(FK constraints preserve resource→agent history).

## Test plan

- N/A (documentation only)
- Verified `/catalog-items` and `/agents` return 200 on live stack

---------

Signed-off-by: Vladislav Kolodny <vkolodny@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.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.

5 participants