Skip to content

OLS-3781: Give verification agent retry autonomy for convergence-dependent checks - #423

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
blublinsky:verification-prompt
Aug 11, 2026
Merged

OLS-3781: Give verification agent retry autonomy for convergence-dependent checks#423
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
blublinsky:verification-prompt

Conversation

@blublinsky

@blublinsky blublinsky commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR improves agent prompt quality, timeout coordination, and sandbox pod lifecycle management.

Verification agent retry autonomy

The verification query template now instructs the agent to autonomously retry convergence-dependent checks (alerts clearing, pods becoming ready, metrics stabilizing) within its sandbox session. Mandatory retry rules with specific cadences and minimum attempts are defined for alert checks (~10 min), pod readiness (~5 min), and metrics checks (~10 min). The agent is prohibited from reporting a single-attempt failure for convergence-dependent checks.

Analysis and execution prompt improvements

  • Cross-service correlation: Analysis agent now checks whether other workloads exhibit the same failure pattern and correlates timestamps across services before diagnosing.
  • App vs infrastructure classification: Agent distinguishes application-logic errors from infrastructure errors and matches remediation scope accordingly.
  • Dependency graph tracing: Agent inspects ConfigMaps, env vars, and connection strings to discover shared backends across namespaces.
  • Verification plan guardrails: Verification plans are constrained to read-only operations the agent actually has access to (no exec, port-forward, services/proxy). Log absence checks use --since instead of large --tail windows.
  • Expected values must be exact: Verification expected values must be concrete observable values (image tag, replica count), not relative descriptions.

Timeout coordination

Previously, step timeouts were hardcoded in Go constants but never communicated to the Python agent — the TimeoutMs field in the HTTP request payload was always empty, so the agent used its own internal default (5 min), which was shorter than the controller's budget.

  • Run() now accepts a timeout time.Duration parameter and populates TimeoutMs in the request payload.
  • The HTTP client timeout is set to stepTimeout + defaultSandboxTimeout (agent budget + 5 min startup allowance).
  • The SandboxAgentCaller.Timeout field is removed; defaultSandboxTimeout is used directly.

Pod activeDeadlineSeconds

Sandbox pods previously had no hard deadline — if the agent process hung and the controller crashed between the HTTP timeout and pod release, the pod would run indefinitely.

  • SandboxLifecycle.Create() now accepts a deadline time.Duration parameter.
  • SandboxManager.Create() sets podSpec.ActiveDeadlineSeconds from the deadline, covering both bare-pod and sandbox-claim modes.
  • The deadline is stepTimeout + defaultSandboxTimeout, matching the HTTP client timeout.

Timeout layering (analysis/execution example, 10 min step):

Layer Value Enforced by
TimeoutMs to agent 10 min Python agent self-limits
HTTP client timeout 15 min Go http.Client kills connection
activeDeadlineSeconds 15 min kubelet hard-kills pod

Test plan

  • Unit tests pass (193 tests in controller/agenticrun, all green)
  • TestAgentHTTPClient_RunSuccess verifies TimeoutMs is serialized correctly in the request payload
  • TestCreate_BarePod asserts ActiveDeadlineSeconds is set on the pod
  • TestCreate_OTELEnvVars_SandboxClaim asserts activeDeadlineSeconds in the SandboxTemplate podTemplate.spec
  • Verify verification agent retries convergence-dependent checks in a real cluster scenario

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

openshift-ci-robot commented Aug 6, 2026

Copy link
Copy Markdown

@blublinsky: This pull request references OLS-3781 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 feature request to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Prompt-only change to the verification query template.

The verification agent now has autonomy to handle convergence-dependent checks (alerts clearing, pods becoming ready, metrics stabilizing) by waiting and retrying within its sandbox session, bounded by the existing sandbox timeout.
No schema, API, or controller logic changes.

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 added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 6, 2026
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Summary by CodeRabbit

  • Improvements
    • Verification results now report each planned check in order with clear Passed/Failed status and supporting evidence.
    • Added guidance for read-only alternatives and limited syntax-only corrections without changing command scope.
    • Convergence checks now include appropriate wait intervals, bounded retries, and final observations.
    • Immediate state checks are not retried, and unrelated checks are excluded.
    • Updated agent guidance for broader cluster environments while preserving inspection and remediation behavior.

Walkthrough

Agent prompts now use cluster-generic roles. Verification requires read-only commands, evidence for each planned check, syntax-only corrections, and bounded retries for convergence-dependent checks. Tests assert the read-only and retry guidance.

Changes

AgenticRun prompt updates

Layer / File(s) Summary
Prompt roles and verification contracts
controller/agenticrun/templates/analysis_query.tmpl, controller/agenticrun/templates/execution_query.tmpl, controller/agenticrun/templates/verification_query.tmpl
Analysis and execution prompts use cluster-generic roles. Verification follows approved-plan order, reports status and evidence, permits syntax-only corrections, prohibits extra checks, and restricts commands to read-only access.
Convergence retries and test coverage
controller/agenticrun/templates/verification_query.tmpl, controller/agenticrun/revision_test.go, controller/agenticrun/sandbox_agent_test.go
Verification adds category-specific waits and ten-retry limits for convergence-dependent checks. Immediate state checks are not retried. Tests assert read-only access and retry guidance.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
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.
Title check ✅ Passed The title clearly identifies the main change: allowing the verification agent to retry convergence-dependent checks.
Description check ✅ Passed The description discusses verification retries and prompt changes that are related to the changeset, despite including additional claims not shown in the summary.

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.

@openshift-ci
openshift-ci Bot requested review from JoaoFula and xrajesh August 6, 2026 11:27

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

Actionable comments posted: 3

🤖 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 `@controller/agenticrun/sandbox_agent_test.go`:
- Around line 543-548: Strengthen the verification-query assertions in the
relevant sandbox agent test by checking each required convergence retry wait
interval, the maximum of five retries, and the rule excluding instant state
checks from retries. Keep the existing heading and generic retry assertions, and
ensure the test validates the complete bounded retry guidance.

In `@controller/agenticrun/templates/verification_query.tmpl`:
- Around line 3-16: Rewrite the verification template so every sentence contains
no more than 20 words. Replace “e.g.” with plain examples, remove “should,” and
preserve all verification, retry, evidence, and reporting requirements.
- Around line 7-16: Update the verification retry logic in the verification
query template to enforce a total deadline based on the remaining sandbox time,
not just per-check retry counts. Before each delayed retry, verify enough time
remains for another attempt; stop when it does not, and report failure with the
last observed value. Preserve later-pass reporting as Passed and keep all
retries within the existing sandbox timeout.
🪄 Autofix

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: Pro Plus

Run ID: 5569ca39-c710-498c-babc-945713653717

📥 Commits

Reviewing files that changed from the base of the PR and between 303f265 and 5fc0273.

📒 Files selected for processing (2)
  • controller/agenticrun/sandbox_agent_test.go
  • controller/agenticrun/templates/verification_query.tmpl
🔗 Linked repositories identified

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

  • openshift/lightspeed-agentic-sandbox (manual)

Comment thread controller/agenticrun/sandbox_agent_test.go
Comment thread controller/agenticrun/templates/verification_query.tmpl Outdated
Comment thread controller/agenticrun/templates/verification_query.tmpl Outdated
@blublinsky
blublinsky force-pushed the verification-prompt branch from 5fc0273 to 6468a8e Compare August 6, 2026 12:24
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 6, 2026
@blublinsky
blublinsky force-pushed the verification-prompt branch from 6468a8e to 5f815f4 Compare August 6, 2026 12:33
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@blublinsky
blublinsky force-pushed the verification-prompt branch from 5f815f4 to 75b182a Compare August 6, 2026 15:39
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@blublinsky
blublinsky force-pushed the verification-prompt branch 2 times, most recently from eee47ba to 9e7484c Compare August 6, 2026 16:31
@@ -1,10 +1,10 @@
You are an analysis agent for OpenShift clusters. Diagnose the problem. Determine the root cause. Produce a remediation plan. A human will review and approve this plan before execution. Do NOT run commands that change the cluster state. You can only read. Write remediation commands for an execution agent to run after human approval.

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.

why delete for OpenShift clusters ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Cause we are running on Openshift cluster. It does not seem to add any useful info

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.

how does the agent know this without encountering oc/kubectl in the prompt. isnt it better to be explicit?

@blublinsky
blublinsky force-pushed the verification-prompt branch from 9e7484c to c4c48af Compare August 6, 2026 16:39
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

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

Code Review

2 finding(s) posted as inline comments on the diff.

🚨 Critical: VerificationStep schema missing retryCount and retryIntervalSeconds fields (AC1 unmet)

api/v1alpha1/agenticrun_analysis_types.go:159

Detail

AC1 requires VerificationStep to gain retryCount and retryIntervalSeconds fields so retry behaviour is configurable per check. The struct at line 159 is unchanged — it still has only Name, Command, Expected, and Type. Without these fields, ACs 2 and 3 also cannot be fully met (the analysis agent cannot populate them, and the verification agent cannot read them). The schema must be extended and make manifests re-run to regenerate CRD YAML.

🚨 Critical: No E2E test for convergence-delayed verification (AC6 unmet)

test/e2e/verification_test.go:1

Detail

AC6 explicitly requires an E2E test that demonstrates alert-based (or convergence-dependent) verification passing after a delay. The diff adds only unit tests (string-contains assertions in sandbox_agent_test.go and revision_test.go). The test/e2e/verification_test.go file is untouched and has no convergence/delay coverage. An E2E test is needed to validate the fix for the field-reported bug (PaymentErrorRateHigh rollback marked failed before alert cleared).


Reviewed by adversarial code review system (4 findings survived verification)

{{- if .HasVerification}}

- **Verification plan** — checks to confirm the fix worked.
- **Verification plan** — checks to confirm the fix worked. The verification agent has **read-only cluster access** (get, list, watch only). Do NOT propose `exec`, `port-forward`, `cp`, `attach`, or `proxy` commands. These require escalated permissions the agent lacks. Use `oc get`, `oc describe`, `oc logs`, `oc get events`, or JSONPath queries.

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.

🚨 CRITICAL: Analysis prompt does not instruct LLM to populate retry hints (AC2 unmet)

AC2 requires the analysis prompt to tell the LLM to fill in retryCount and retryIntervalSeconds based on check type (e.g., metric checks get retryCount=5/retryIntervalSeconds=30, instant-state checks get retryCount=0). The only change to analysis_query.tmpl is adding a read-only access constraint to the verification plan bullet. No retry classification guidance was added. Without this, the analysis agent produces VerificationSteps with no retry metadata, leaving the verification agent to guess convergence type from free-form descriptions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Adding retryCount/retryIntervalSeconds to VerificationStep means the analysis agent has to predict convergence behavior before execution even happens. The verification agent runs after execution — it sees the actual command output ("0/1 Ready", "alert still firing") and is in a far better position to judge whether to wait. Structured retry metadata would be the analysis agent guessing at something the verification agent can observe.


**Fix syntax errors only.** If a command fails due to a syntax error (malformed flag, wrong argument order), fix the syntax and retry. Do not change the intent, target, or resource of the command. Do not add checks beyond the verification plan.

### Convergence-dependent checks

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.

⚠️ Warning: Retry tier labels not anchored to VerificationStep.type field — agent must guess from free text

The template defines retry tiers by descriptive labels (Alerts, Pod readiness/rollout, Metrics, Instant state checks), but the VerificationStep.Type field arriving in .OptionJSON is a free-form string whose example values in the schema comment are 'command', 'metric', 'condition'. Neither the analysis prompt nor this template establishes a mapping between those type values and the retry categories. A convergence-dependent check with type='command' will likely be classified as 'Instant state' by the verification agent and not retried. Fix: either enumerate allowed type values in the schema (e.g., 'alert', 'pod-readiness', 'metric', 'instant') and reference them explicitly in both templates, or add a boolean convergence: true field to VerificationStep so the analysis agent can tag checks unambiguously.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The verification agent doesn't need to classify by VerificationStep.type to decide whether to retry. It runs the command, sees the output, and reasons about it. If oc get pods returns "0/1 Ready" after a rollout restart, the agent knows to wait regardless of whether type says command or pod-readiness. That's the whole value of having an LLM do verification — it reasons per-case, not by category.

@vimalk78

vimalk78 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Code Review

2 finding(s) posted as inline comments on the diff.

🚨 Critical: VerificationStep schema missing retryCount and retryIntervalSeconds fields (AC1 unmet)

api/v1alpha1/agenticrun_analysis_types.go:159

Detail

AC1 requires VerificationStep to gain retryCount and retryIntervalSeconds fields so retry behaviour is configurable per check. The struct at line 159 is unchanged — it still has only Name, Command, Expected, and Type. Without these fields, ACs 2 and 3 also cannot be fully met (the analysis agent cannot populate them, and the verification agent cannot read them). The schema must be extended and make manifests re-run to regenerate CRD YAML.

🚨 Critical: No E2E test for convergence-delayed verification (AC6 unmet)

test/e2e/verification_test.go:1

Detail

AC6 explicitly requires an E2E test that demonstrates alert-based (or convergence-dependent) verification passing after a delay. The diff adds only unit tests (string-contains assertions in sandbox_agent_test.go and revision_test.go). The test/e2e/verification_test.go file is untouched and has no convergence/delay coverage. An E2E test is needed to validate the fix for the field-reported bug (PaymentErrorRateHigh rollback marked failed before alert cleared).


Reviewed by adversarial code review system (4 findings survived verification)

@blublinsky

Copy link
Copy Markdown
Contributor Author

Analysis knows what and how to verify, but it does not have the state of the cluster during verification. The verification agent has up-to-date information about the cluster and is in a much better position to decide when and where to do retries.

@blublinsky

Copy link
Copy Markdown
Contributor Author

Re: E2E test for convergence-delayed verification — this is a prompt-only change. Convergence retry behavior happens inside the LLM's reasoning within the sandbox — there's no controller logic to E2E test. The sandbox timeout is the existing E2E-testable boundary. You could theoretically set up a slow-converging fixture, but that would be testing the LLM's compliance with the prompt, not the operator.

@vimalk78

vimalk78 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 7, 2026
@blublinsky
blublinsky force-pushed the verification-prompt branch from c4c48af to 1c2999a Compare August 7, 2026 13:58
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Aug 7, 2026
@blublinsky
blublinsky force-pushed the verification-prompt branch 3 times, most recently from cb2d472 to 302e435 Compare August 10, 2026 11:24
@blublinsky
blublinsky force-pushed the verification-prompt branch 3 times, most recently from 8b2fb2b to 56ee115 Compare August 10, 2026 17:47
@blublinsky
blublinsky force-pushed the verification-prompt branch 2 times, most recently from 60a1636 to a8398d6 Compare August 11, 2026 10:50

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

Code Review

5 finding(s) posted as inline comments on the diff.

🚨 Critical: VerificationStep schema missing retryCount and retryIntervalSeconds fields (AC1 unmet)

api/v1alpha1/agenticrun_analysis_types.go:159

Detail

AC1 requires VerificationStep to gain retryCount and retryIntervalSeconds fields so the analysis agent can annotate per-step retry budgets. The PR deliberately chose a different approach (hardcoded per-category retry rules in the verification prompt) instead of schema changes. The struct and the JSON schema in schemas.go are unchanged. AC1 as written is not met. If the team accepts the prompt-based approach as the final design, the AC should be updated in Jira and the schemas.go type values aligned with the new check-category vocabulary (alert, metric, pod-readiness, log-absence, instant).

🚨 Critical: No E2E test for convergence-delayed verification (AC6 unmet)

test/e2e/verification_test.go:1

Detail

AC6 requires an E2E test demonstrating that alert-based verification passes after delayed convergence. The file still contains only TestVerificationFlow_VerifyingToCompleted, which drives the mock agent to an immediate pass. No test exercises the new MANDATORY RETRY RULES in the verification template or confirms that a check passing on retry N is reported as Passed rather than Failed.

⚠️ Warning: allPassed initialized from verifyResult.Success; loop never flips it back to true

controller/agenticrun/handlers.go:486

Detail

allPassed is initialized to verifyResult.Success on line 486. The subsequent loop over verifyResult.Checks can only assign false, never true. If the LLM returns a top-level success=false (e.g., due to a schema parsing edge case or miscalibrated agent output) while all individual Checks report Passed, allPassed stays false and triggers a spurious execution retry. Fix: initialize to true and derive solely from individual check results: allPassed := true; for _, check := range verifyResult.Checks { if check.Result != CheckResultPassed { allPassed = false; break } }.

⚠️ Warning: Operator restart during convergence retry can leave run permanently stuck at Verified=Unknown

controller/agenticrun/handlers.go:472

Detail

handlers.go is unchanged. If the operator crashes between setting Verified=Unknown and recording the verification sandbox name in status, the reconciler on restart sees Verified=Unknown and attempts to spawn another sandbox. If the status patch was not persisted, the run cycles indefinitely. No idempotency guard (e.g., check whether a sandbox is already live before spawning) was added to protect this path. This pre-existing issue was not addressed by the PR.

⚠️ Warning: +required marker conflicts with omitempty JSON tag on Confidence field

api/v1alpha1/agenticrun_analysis_types.go:73

Detail

The Confidence field on DiagnosisResult has // +required but json:"confidence,omitempty". The omitempty tag causes the field to be omitted from serialized output when the zero value, directly contradicting the required marker. The generated CRD will not enforce presence. Fix: remove omitempty from the tag (json:"confidence") or change the marker to +optional. Same pattern exists on Risk (line 143).

⚠️ Warning: +required marker conflicts with omitempty JSON tag on Risk field

api/v1alpha1/agenticrun_analysis_types.go:143

Detail

Same issue as line 73 (Confidence). The Risk field on RemediationPlan has // +required but json:"risk,omitempty". The omitempty tag means the zero value is not serialized, contradicting the required semantics. Fix: remove omitempty from the tag (json:"risk") or change the marker to +optional.


Reviewed by adversarial code review system (11 findings survived verification)

@@ -40,7 +48,13 @@ When more than one solution exists, propose multiple remediation options. For ea
{{- end}}
{{- if .HasVerification}}

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.

🚨 CRITICAL: Analysis prompt does not instruct LLM to populate retry hints (AC2 unmet)

AC2 requires the analysis prompt to instruct the LLM to populate retryCount/retryIntervalSeconds for convergence-dependent checks. The template was updated with scope-analysis guidance and verification read-only constraints, but contains no instruction to populate retry fields. Since the PR chose hardcoded prompt rules instead of schema-driven retries, AC2 is effectively superseded — but neither the AC nor the Jira story reflects this design change. The implementation gap should be explicitly acknowledged.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We already been over this. Retries are NOT analysis business anymore. Its specifies what to check. Verification decides what is worth retrying


**Exception — log absence checks:** If a check asserts an error is gone, rewrite a large `--tail` to `--since=2m` or `--since=5m`. Example of a large tail: `--tail=100`. Large tails retain pre-fix lines and cause false failures. Keep the same resource and message. Only change the log window.

### Convergence-dependent checks — MANDATORY RETRY RULES

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.

⚠️ Warning: Combined convergence retry budgets can reach or exceed verificationStepTimeout with no margin

verificationStepTimeout is 30 minutes. The MANDATORY RETRY RULES define: alert=~10 min, metrics=~10 min, log-absence=~10 min, pod-readiness=~5 min. A plan with alert+metrics+log-absence all failing at max retries consumes exactly 30 minutes — the full budget — before any execution overhead or other checks. The agent receives no instruction to manage a global time budget across checks; it will dutifully follow each check's full retry sequence and get killed mid-verification by the HTTP timeout, producing an opaque failure rather than a clean partial result. Fix: add a note in the template instructing the agent to distribute time budget across checks, or increase verificationStepTimeout to provide a safety margin.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fair point, but need testing and potentially extending execution time. Not in this PR

@@ -1,6 +1,28 @@
You are a verification agent for OpenShift clusters. Verify that the executed remediation was applied correctly. Verify that the issue is resolved. Do not execute any additional changes. Only verify.
You are a verification agent. Verify that the issue is resolved. Do not execute changes — only verify.

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.

⚠️ Warning: Verification template has no explicit exec/port-forward prohibition

The analysis template now explicitly lists prohibited commands (exec, port-forward, cp, attach, proxy, get --raw) that must not appear in verification plans. However, the verification template itself only says 'Do not execute changes — only verify.' An LLM could still issue kubectl exec pod -- cat /config for read-only inspection, which would fail at runtime with a permissions error since the verification service account lacks pods/exec. The verification template should reinforce the same prohibition list that the analysis template now provides.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In theory - yes. In practice it does not

@@ -540,6 +538,12 @@ func TestSandboxAgentCaller_VerificationQueryFraming(t *testing.T) {
if strings.Contains(httpClient.lastQuery, "Pod crashing with OOMKilled") {

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.

💡 Suggestion: TestSandboxAgentCaller_VerificationQueryFraming missing assertions for syntax-fix and instant-state-check rules

The test was updated with assertions for 'Convergence-dependent checks' and 'before you are permitted to report Failed', but still lacks assertions for the 'Fix syntax errors only' clause and the 'Instant state checks: do not retry' rule — both now in the template and critical to verification agent behavior. Add: strings.Contains(query, "Fix syntax errors only") and strings.Contains(query, "Instant state checks").

@@ -92,6 +92,12 @@ func TestBuildAnalysisQuery_FullAgenticRun(t *testing.T) {
if !strings.Contains(result, "Verification plan") {

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.

💡 Suggestion: Test checks 'read-only cluster access' but not the prohibited commands list

TestBuildAnalysisQuery_FullAgenticRun was updated to assert 'read-only cluster access' and 'Expected must be an exact observable value', but does not verify that the prohibited-commands list (exec, port-forward, cp, attach, proxy) appears in the generated query. Add an assertion for one of these terms to ensure the prohibition text survives template edits.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was added as a result of testing

@vimalk78

Copy link
Copy Markdown
Contributor

Review Update — Response Judgment

After reviewing the author's responses to 11 finding(s):

Dropped (2)

  • api/v1alpha1/agenticrun_analysis_types.go:159 — VerificationStep schema missing retryCount and retryIntervalSeconds fields (AC1 unmet)

    Author gives a coherent architectural rationale — analysis now specifies what to check; retry policy is verification's responsibility — which would make retryCount/retryIntervalSeconds misplaced in the analysis schema.

  • controller/agenticrun/templates/analysis_query.tmpl:49 — Analysis prompt does not instruct LLM to populate retry hints (AC2 unmet)

    Same architectural argument applies: if retries are no longer analysis's concern, instructing the LLM to emit retry hints in the analysis prompt is also out of scope; AC2 may need to be revisited.

Unresolved (9)

  • 🚨 test/e2e/verification_test.go:1 — No E2E test for convergence-delayed verification (AC6 unmet)
  • ⚠️ controller/agenticrun/handlers.go:486 — allPassed initialized from verifyResult.Success; loop never flips it back to true
  • ⚠️ controller/agenticrun/templates/verification_query.tmpl:9 — Combined convergence retry budgets can reach or exceed verificationStepTimeout with no margin
  • ⚠️ controller/agenticrun/templates/verification_query.tmpl:1 — Verification template has no explicit exec/port-forward prohibition
  • ⚠️ controller/agenticrun/handlers.go:472 — Operator restart during convergence retry can leave run permanently stuck at Verified=Unknown
  • ⚠️ api/v1alpha1/agenticrun_analysis_types.go:73 — +required marker conflicts with omitempty JSON tag on Confidence field
  • ⚠️ api/v1alpha1/agenticrun_analysis_types.go:143 — +required marker conflicts with omitempty JSON tag on Risk field
  • 💡 controller/agenticrun/sandbox_agent_test.go:538 — TestSandboxAgentCaller_VerificationQueryFraming missing assertions for syntax-fix and instant-state-check rules
  • 💡 controller/agenticrun/revision_test.go:92 — Test checks 'read-only cluster access' but not the prohibited commands list

1 critical finding(s) still need attention.


Adversarial code review system — response judgment

@vimalk78

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 11, 2026
@blublinsky
blublinsky force-pushed the verification-prompt branch from a8398d6 to c30dea4 Compare August 11, 2026 12:33
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Aug 11, 2026
@rioloc

rioloc commented Aug 11, 2026

Copy link
Copy Markdown
Member

Following up on our joint investigation and testing around the verification issues, here are the latest results before approving:

We successfully ran and verified the retries mechanism. While non-deterministic model behavior can still occasionally result in an invalid plan or sporadic failure, the flow is now working reliably when a valid plan is proposed (we can capture precise metrics once verification evals are in place).

When the model generates a solid plan, retries function as expected, and the previous timing and synchronization issues between execution end and verification start appear fully resolved.

Please keep in mind that retries add time to the process. For scenarios involving retries where log analysis is involved until a certain state is reached, verification can take anywhere from 6 to 13 minutes based on my recent successful runs.

@rioloc

rioloc commented Aug 11, 2026

Copy link
Copy Markdown
Member

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 11, 2026
@blublinsky

Copy link
Copy Markdown
Contributor Author

/approve

@openshift-ci

openshift-ci Bot commented Aug 11, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: blublinsky

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

The pull request process is described 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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 11, 2026
@openshift-ci

openshift-ci Bot commented Aug 11, 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.

@openshift-merge-bot
openshift-merge-bot Bot merged commit 547d20d into openshift:main Aug 11, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants