Skip to content

OLS-2989: Implement operator-side metrics envelope parsing and Result CR storage#133

Open
blublinsky wants to merge 1 commit into
openshift:mainfrom
blublinsky:metric-envelope
Open

OLS-2989: Implement operator-side metrics envelope parsing and Result CR storage#133
blublinsky wants to merge 1 commit into
openshift:mainfrom
blublinsky:metric-envelope

Conversation

@blublinsky

Copy link
Copy Markdown
Contributor

Summary
Implements the operator side of the sandbox → operator metrics handoff (companion to lightspeed-agentic-sandbox#74). The agent's POST /v1/agent/run response is now a {metrics, result} envelope. The operator parses the envelope, threads metrics through the call chain, and persists them on Result CR statuses.

Design decisions
StepMetrics on Result CR status (not Prometheus, not Proposal status): Result CRs are the source of truth per-step. Metrics live with the step's outcome. Prometheus/export can be added later by reading these fields.
CostUSD as string: controller-gen rejects float64 for cross-language portability. String with regex validation (^\d+(.\d+)?$) is the standard pattern.
toStepMetrics(nil) → nil: Failure paths (where agent didn't respond) don't produce empty metric blocks.
Envelope validation: Missing result field fails immediately with a clear error rather than silently producing nil output.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 16, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 16, 2026

Copy link
Copy Markdown

@blublinsky: This pull request references OLS-2989 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary
Implements the operator side of the sandbox → operator metrics handoff (companion to lightspeed-agentic-sandbox#74). The agent's POST /v1/agent/run response is now a {metrics, result} envelope. The operator parses the envelope, threads metrics through the call chain, and persists them on Result CR statuses.

Design decisions
StepMetrics on Result CR status (not Prometheus, not Proposal status): Result CRs are the source of truth per-step. Metrics live with the step's outcome. Prometheus/export can be added later by reading these fields.
CostUSD as string: controller-gen rejects float64 for cross-language portability. String with regex validation (^\d+(.\d+)?$) is the standard pattern.
toStepMetrics(nil) → nil: Failure paths (where agent didn't respond) don't produce empty metric blocks.
Envelope validation: Missing result field fails immediately with a clear error rather than silently producing nil output.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot requested review from harche and raptorsun June 16, 2026 12:37
@openshift-ci

openshift-ci Bot commented Jun 16, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign blublinsky for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@blublinsky, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 13 minutes and 16 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cc1fee44-8c46-4656-94ee-9f688ad22240

📥 Commits

Reviewing files that changed from the base of the PR and between 6a4f6fc and 356fff5.

⛔ Files ignored due to path filters (4)
  • config/crd/bases/agentic.openshift.io_analysisresults.yaml is excluded by !config/crd/bases/**
  • config/crd/bases/agentic.openshift.io_escalationresults.yaml is excluded by !config/crd/bases/**
  • config/crd/bases/agentic.openshift.io_executionresults.yaml is excluded by !config/crd/bases/**
  • config/crd/bases/agentic.openshift.io_verificationresults.yaml is excluded by !config/crd/bases/**
📒 Files selected for processing (15)
  • .ai/spec/how/reconciler.md
  • .ai/spec/what/sandbox-execution.md
  • api/v1alpha1/analysisresult_types.go
  • api/v1alpha1/escalationresult_types.go
  • api/v1alpha1/executionresult_types.go
  • api/v1alpha1/shared_types.go
  • api/v1alpha1/verificationresult_types.go
  • controller/proposal/agent.go
  • controller/proposal/client.go
  • controller/proposal/client_test.go
  • controller/proposal/reconciler_test.go
  • controller/proposal/results.go
  • controller/proposal/sandbox_agent.go
  • controller/proposal/sandbox_agent_test.go
  • test/agent/main.go
📝 Walkthrough

Walkthrough

Adds StepMetrics CRD type and RunMetrics controller type to carry LLM telemetry from sandbox agents. Changes the agent HTTP response contract from a raw payload to a {metrics, result} envelope. Propagates metrics through the HTTP client, callWithSandbox, four *Output structs, a toStepMetrics converter, and finally into all Result CR statuses.

Changes

Metrics Collection and Storage

Layer / File(s) Summary
Schema types and Result status fields
api/v1alpha1/shared_types.go, api/v1alpha1/analysisresult_types.go, api/v1alpha1/executionresult_types.go, api/v1alpha1/verificationresult_types.go, api/v1alpha1/escalationresult_types.go
Defines StepMetrics struct with kubebuilder validation constraints (latency, token counts, cost, model, provider, tool calls). Adds optional Metrics StepMetrics field to all four *ResultStatus types with json:"metrics,omitzero" serialization. Removes MinProperties=1 validation markers.
HTTP response envelope and parsing
controller/proposal/client.go
Introduces RunMetrics type mirroring agent response telemetry fields. Changes agentRunResponse from single Response field to envelope with Metrics *RunMetrics and Result json.RawMessage. Updates Run method to unmarshal response body into envelope and error if result is missing or null.
HTTP client envelope tests
controller/proposal/client_test.go
Updates mock HTTP responses across all test cases to provide {metrics, result} envelope structure. Adds assertions validating non-empty Result and non-nil Metrics fields.
Sandbox agent metrics capture and Output propagation
controller/proposal/agent.go, controller/proposal/sandbox_agent.go
Adds Metrics *RunMetrics field to all four *Output structs. Changes callWithSandbox signature to return (json.RawMessage, *RunMetrics, error). Updates Analyze, Execute, Verify, and Escalate methods to capture metrics from callWithSandbox and set on respective output struct. Returns nil metrics on error paths.
Result CR status metric storage
controller/proposal/results.go
Adds toStepMetrics helper to convert *RunMetricsStepMetrics with nil guard and conditional CostUSD copy. Updates all four createAnalysisResult, createExecutionResult, createVerificationResult, createEscalationResult functions to set cr.Status.Metrics via toStepMetrics.
Mock integration and end-to-end tests
controller/proposal/sandbox_agent_test.go, controller/proposal/reconciler_test.go, test/agent/main.go
Renames Response to Result in all mock agentRunResponse constructions across 20+ sandbox agent tests. Updates reconciler test mock to use new field. Wraps mock agent server's canned responses in {metrics, result} envelope.
HTTP contract and spec documentation
.ai/spec/how/reconciler.md, .ai/spec/what/sandbox-execution.md
Documents SandboxAgentCaller and AgentHTTPClient Run contract: empty systemPrompt, full payload POST, new {metrics, result} envelope, and RunMetrics fields. Mandates storing metrics on Result CR status without using them for workflow decisions.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: implementing operator-side metrics envelope parsing and persisting metrics to Result CR status.
Description check ✅ Passed The description clearly relates to the changeset, explaining the metrics envelope parsing, threading through the call chain, and CR storage, with documented design decisions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
controller/proposal/results.go (1)

290-320: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add Metrics field copy to all four Result types.

copyResultStatus updates existing Result CRs on AlreadyExists but does not copy the Metrics field. When createIdempotent encounters an existing CR (e.g., reconcile retry), the metrics from the latest agent response are lost.

Add d.Status.Metrics = s.Status.Metrics in each case block to persist metrics consistently.

🔧 Proposed fix
 func copyResultStatus(dst, src client.Object) {
 	switch d := dst.(type) {
 	case *agenticv1alpha1.AnalysisResult:
 		if s, ok := src.(*agenticv1alpha1.AnalysisResult); ok {
 			d.Status.Options = s.Status.Options
 			d.Status.FailureReason = s.Status.FailureReason
 			d.Status.Sandbox = s.Status.Sandbox
+			d.Status.Metrics = s.Status.Metrics
 		}
 	case *agenticv1alpha1.ExecutionResult:
 		if s, ok := src.(*agenticv1alpha1.ExecutionResult); ok {
 			d.Status.ActionsTaken = s.Status.ActionsTaken
 			d.Status.Verification = s.Status.Verification
 			d.Status.FailureReason = s.Status.FailureReason
 			d.Status.Sandbox = s.Status.Sandbox
+			d.Status.Metrics = s.Status.Metrics
 		}
 	case *agenticv1alpha1.VerificationResult:
 		if s, ok := src.(*agenticv1alpha1.VerificationResult); ok {
 			d.Status.Checks = s.Status.Checks
 			d.Status.Summary = s.Status.Summary
 			d.Status.FailureReason = s.Status.FailureReason
 			d.Status.Sandbox = s.Status.Sandbox
+			d.Status.Metrics = s.Status.Metrics
 		}
 	case *agenticv1alpha1.EscalationResult:
 		if s, ok := src.(*agenticv1alpha1.EscalationResult); ok {
 			d.Status.Summary = s.Status.Summary
 			d.Status.Content = s.Status.Content
 			d.Status.FailureReason = s.Status.FailureReason
 			d.Status.Sandbox = s.Status.Sandbox
+			d.Status.Metrics = s.Status.Metrics
 		}
 	}
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controller/proposal/results.go` around lines 290 - 320, The copyResultStatus
function copies various status fields for all four Result types (AnalysisResult,
ExecutionResult, VerificationResult, EscalationResult) but omits the Metrics
field, causing metrics data to be lost when updating existing CRs during
reconcile retries. Add d.Status.Metrics = s.Status.Metrics to each of the four
case blocks in copyResultStatus (the AnalysisResult case, ExecutionResult case,
VerificationResult case, and EscalationResult case) to ensure metrics are
consistently persisted alongside the other status fields.
🧹 Nitpick comments (1)
test/agent/main.go (1)

154-163: 💤 Low value

Mock envelope construction is functional but consider structured marshaling.

The envelope is built via string formatting rather than marshaling a struct. This works since cannedResponse returns valid JSON that can be directly embedded, but using json.Marshal on a struct would be more maintainable if response formats evolve.

♻️ Optional refactor for type safety
-	result := cannedResponse(phase, ns)
-
-	envelope := fmt.Sprintf(`{"metrics":{"latency_ms":1500,"input_tokens":100,"output_tokens":50,"model":"mock-model","provider":"mock","tool_calls_count":1},"result":%s}`, string(result))
+	result := cannedResponse(phase, ns)
+	
+	envelope := map[string]interface{}{
+		"metrics": map[string]interface{}{
+			"latency_ms":       1500,
+			"input_tokens":     100,
+			"output_tokens":    50,
+			"model":            "mock-model",
+			"provider":         "mock",
+			"tool_calls_count": 1,
+		},
+		"result": json.RawMessage(result),
+	}
+	envelopeJSON, err := json.Marshal(envelope)
+	if err != nil {
+		log.Printf("marshal envelope: %v", err)
+		http.Error(w, "internal error", http.StatusInternalServerError)
+		return
+	}
 
 	w.Header().Set("Content-Type", "application/json")
 	w.WriteHeader(http.StatusOK)
-	if _, err := w.Write([]byte(envelope)); err != nil {
+	if _, err := w.Write(envelopeJSON); err != nil {
 		log.Printf("write response: %v", err)
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/agent/main.go` around lines 154 - 163, The envelope in the mock response
handler is constructed using fmt.Sprintf with a hardcoded JSON string template,
which reduces maintainability if response formats evolve. Instead, define a
struct type that represents the response envelope with fields for metrics
(containing latency_ms, input_tokens, output_tokens, model, provider,
tool_calls_count) and result, then use json.Marshal to serialize this struct
with the actual values from cannedResponse and the metrics data. This approach
provides better type safety and makes future format changes easier to manage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.ai/spec/how/reconciler.md:
- Around line 138-140: The RunMetrics documentation in reconciler.md at line 140
incorrectly documents CostUSD as `*float64`, but the actual implementation uses
`*string` validated with regex pattern `^\d+(\.\d+)?$`. Update the CostUSD field
documentation to reflect the correct type as `*string` and note that it is
validated with the regex pattern to maintain consistency with the actual
implementation that uses this approach for cross-language portability.

In `@api/v1alpha1/shared_types.go`:
- Around line 198-208: Add non-negative validation constraints to the metric
counter and latency fields in the shared_types.go file. For the fields
LatencyMs, InputTokens, OutputTokens, and the additional field at line 228 (as
noted in the comment), add a kubebuilder validation marker (such as
`+kubebuilder:validation:Minimum=0`) above each field definition to enforce that
these fields can only accept zero or positive integer values, preventing invalid
telemetry data with negative values from being stored in status.

In `@controller/proposal/client.go`:
- Around line 149-151: The nil check on the response.Result field in the
validation block only rejects missing fields but allows null values to pass
through, meaning a response with `{"result":null}` would silently proceed to
downstream unmarshalling. Modify the validation logic to explicitly reject cases
where the result field is explicitly set to null, not just missing, by adding an
additional check after the nil validation or by using a pointer field that
distinguishes between absent and null values during JSON unmarshalling.
- Around line 145-153: The code enforces that the agentRunResponse must contain
a non-nil result field, but the current sandbox agent returns a legacy format
with success and summary fields instead. To support mixed-version deployments,
add a fallback parsing mechanism: after unmarshaling into agentRunResponse,
check if result is nil, and if so, attempt to parse the response body into a
legacy response structure (with success and summary fields). Convert the legacy
format to the envelope format or handle it separately, ensuring backward
compatibility before raising an error for missing result field.

---

Outside diff comments:
In `@controller/proposal/results.go`:
- Around line 290-320: The copyResultStatus function copies various status
fields for all four Result types (AnalysisResult, ExecutionResult,
VerificationResult, EscalationResult) but omits the Metrics field, causing
metrics data to be lost when updating existing CRs during reconcile retries. Add
d.Status.Metrics = s.Status.Metrics to each of the four case blocks in
copyResultStatus (the AnalysisResult case, ExecutionResult case,
VerificationResult case, and EscalationResult case) to ensure metrics are
consistently persisted alongside the other status fields.

---

Nitpick comments:
In `@test/agent/main.go`:
- Around line 154-163: The envelope in the mock response handler is constructed
using fmt.Sprintf with a hardcoded JSON string template, which reduces
maintainability if response formats evolve. Instead, define a struct type that
represents the response envelope with fields for metrics (containing latency_ms,
input_tokens, output_tokens, model, provider, tool_calls_count) and result, then
use json.Marshal to serialize this struct with the actual values from
cannedResponse and the metrics data. This approach provides better type safety
and makes future format changes easier to manage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f88df944-d6fc-4694-b8ed-d0612f147d7a

📥 Commits

Reviewing files that changed from the base of the PR and between 7dba1ba and e39844f.

⛔ Files ignored due to path filters (4)
  • config/crd/bases/agentic.openshift.io_analysisresults.yaml is excluded by !config/crd/bases/**
  • config/crd/bases/agentic.openshift.io_escalationresults.yaml is excluded by !config/crd/bases/**
  • config/crd/bases/agentic.openshift.io_executionresults.yaml is excluded by !config/crd/bases/**
  • config/crd/bases/agentic.openshift.io_verificationresults.yaml is excluded by !config/crd/bases/**
📒 Files selected for processing (15)
  • .ai/spec/how/reconciler.md
  • .ai/spec/what/sandbox-execution.md
  • api/v1alpha1/analysisresult_types.go
  • api/v1alpha1/escalationresult_types.go
  • api/v1alpha1/executionresult_types.go
  • api/v1alpha1/shared_types.go
  • api/v1alpha1/verificationresult_types.go
  • controller/proposal/agent.go
  • controller/proposal/client.go
  • controller/proposal/client_test.go
  • controller/proposal/reconciler_test.go
  • controller/proposal/results.go
  • controller/proposal/sandbox_agent.go
  • controller/proposal/sandbox_agent_test.go
  • test/agent/main.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift/lightspeed-agentic-sandbox (manual)

Comment thread .ai/spec/how/reconciler.md
Comment thread api/v1alpha1/shared_types.go Outdated
Comment on lines +145 to +153
var response agentRunResponse
if err := json.Unmarshal(respBody, &response); err != nil {
return nil, fmt.Errorf("parse response envelope: %w", err)
}
if response.Result == nil {
return nil, fmt.Errorf("response envelope missing 'result' field")
}

return &response, nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the full context of the client.go file around lines 145-153
wc -l controller/proposal/client.go

Repository: openshift/lightspeed-agentic-operator

Length of output: 115


🏁 Script executed:

#!/bin/bash
# Read the full response parsing and agentRunResponse struct definition
sed -n '1,200p' controller/proposal/client.go | cat -n

Repository: openshift/lightspeed-agentic-operator

Length of output: 5978


🏁 Script executed:

#!/bin/bash
# Search for agentRunResponse struct definition
rg -A 10 "type agentRunResponse struct"

Repository: openshift/lightspeed-agentic-operator

Length of output: 862


🏁 Script executed:

#!/bin/bash
# Check if there's any fallback or version detection logic
rg -n "success\|summary\|legacy\|fallback\|version" controller/proposal/client.go | head -30

Repository: openshift/lightspeed-agentic-operator

Length of output: 63


🏁 Script executed:

#!/bin/bash
# Check for any deployment coordination or version detection logic
rg -n "Metrics\|Result\|envelope" controller/proposal/client.go | head -20

Repository: openshift/lightspeed-agentic-operator

Length of output: 63


🏁 Script executed:

#!/bin/bash
# Check where the response is used after parsing - does code handle nil Metrics?
rg -A 5 -B 5 "agentRunResponse" controller/proposal/reconciler.go | head -50

Repository: openshift/lightspeed-agentic-operator

Length of output: 63


🏁 Script executed:

#!/bin/bash
# Verify current agent response format to confirm it's legacy
grep -r "success\|summary" src/lightspeed_agentic/routes/models.py | head -20

Repository: openshift/lightspeed-agentic-sandbox

Length of output: 115


🏁 Script executed:

#!/bin/bash
# Find where Run() result is used and how response is processed
rg -n "\.Run\(" controller/proposal/

Repository: openshift/lightspeed-agentic-operator

Length of output: 3885


🏁 Script executed:

#!/bin/bash
# Search more broadly for response handling
find controller/proposal -name "*.go" -exec grep -l "agentRunResponse\|response\." {} \;

Repository: openshift/lightspeed-agentic-operator

Length of output: 192


🏁 Script executed:

#!/bin/bash
# Check the full reconciler to see response usage
wc -l controller/proposal/reconciler.go
sed -n '1,50p' controller/proposal/reconciler.go | cat -n

Repository: openshift/lightspeed-agentic-operator

Length of output: 3109


🏁 Script executed:

#!/bin/bash
# Check sandbox_agent.go to see how the response is processed
sed -n '200,230p' controller/proposal/sandbox_agent.go | cat -n

Repository: openshift/lightspeed-agentic-operator

Length of output: 1197


🏁 Script executed:

#!/bin/bash
# Look for broader response handling around line 213
sed -n '190,240p' controller/proposal/sandbox_agent.go | cat -n

Repository: openshift/lightspeed-agentic-operator

Length of output: 1823


🏁 Script executed:

#!/bin/bash
# Check client_test.go to see what the test expects
cat -n controller/proposal/client_test.go | head -100

Repository: openshift/lightspeed-agentic-operator

Length of output: 4165


Envelope parsing requires result field; missing compatibility with current agent's legacy format.

The code hard-requires a result field in the agent response (line 149 errors if missing). The current sandbox agent returns legacy {success, summary} format, not the envelope structure. Mixed-version deployments will fail at runtime when the client receives legacy responses and finds result empty.

The metrics field is optional (pointer), but the version-skew break is real. Confirm rollout coordination or add a legacy fallback parser before shipping independently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controller/proposal/client.go` around lines 145 - 153, The code enforces that
the agentRunResponse must contain a non-nil result field, but the current
sandbox agent returns a legacy format with success and summary fields instead.
To support mixed-version deployments, add a fallback parsing mechanism: after
unmarshaling into agentRunResponse, check if result is nil, and if so, attempt
to parse the response body into a legacy response structure (with success and
summary fields). Convert the legacy format to the envelope format or handle it
separately, ensuring backward compatibility before raising an error for missing
result field.

Source: Linked repositories

Comment thread controller/proposal/client.go Outdated

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api/v1alpha1/analysisresult_types.go`:
- Around line 53-55: The new Metrics field added to AnalysisResultStatus in the
AnalysisResult type is not being preserved when status updates occur. In the
copyResultStatus helper function in controller/proposal/results.go, locate the
branch that handles *AnalysisResult and add a line to copy the Metrics field
from the source Status to the destination Status, ensuring telemetry data is not
lost during status copy/update operations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4c4aa20f-9473-4b13-8ff7-60a0e7e53678

📥 Commits

Reviewing files that changed from the base of the PR and between e39844f and 6a4f6fc.

⛔ Files ignored due to path filters (4)
  • config/crd/bases/agentic.openshift.io_analysisresults.yaml is excluded by !config/crd/bases/**
  • config/crd/bases/agentic.openshift.io_escalationresults.yaml is excluded by !config/crd/bases/**
  • config/crd/bases/agentic.openshift.io_executionresults.yaml is excluded by !config/crd/bases/**
  • config/crd/bases/agentic.openshift.io_verificationresults.yaml is excluded by !config/crd/bases/**
📒 Files selected for processing (15)
  • .ai/spec/how/reconciler.md
  • .ai/spec/what/sandbox-execution.md
  • api/v1alpha1/analysisresult_types.go
  • api/v1alpha1/escalationresult_types.go
  • api/v1alpha1/executionresult_types.go
  • api/v1alpha1/shared_types.go
  • api/v1alpha1/verificationresult_types.go
  • controller/proposal/agent.go
  • controller/proposal/client.go
  • controller/proposal/client_test.go
  • controller/proposal/reconciler_test.go
  • controller/proposal/results.go
  • controller/proposal/sandbox_agent.go
  • controller/proposal/sandbox_agent_test.go
  • test/agent/main.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift/lightspeed-agentic-sandbox (manual)
✅ Files skipped from review due to trivial changes (2)
  • .ai/spec/how/reconciler.md
  • controller/proposal/sandbox_agent_test.go
🚧 Files skipped from review as they are similar to previous changes (9)
  • controller/proposal/reconciler_test.go
  • test/agent/main.go
  • api/v1alpha1/shared_types.go
  • controller/proposal/results.go
  • .ai/spec/what/sandbox-execution.md
  • controller/proposal/client.go
  • controller/proposal/sandbox_agent.go
  • controller/proposal/agent.go
  • controller/proposal/client_test.go

Comment thread api/v1alpha1/analysisresult_types.go
@blublinsky blublinsky force-pushed the metric-envelope branch 2 times, most recently from e87be40 to 356fff5 Compare June 16, 2026 15:40
@openshift-ci

openshift-ci Bot commented Jun 17, 2026

Copy link
Copy Markdown

@blublinsky: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

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

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants