Skip to content

OLS-3223: Fix ProposalApproval creation for analysis-only proposals#55

Open
onmete wants to merge 1 commit into
openshift:mainfrom
onmete:fix/ols-3223-advisory-approval-creation
Open

OLS-3223: Fix ProposalApproval creation for analysis-only proposals#55
onmete wants to merge 1 commit into
openshift:mainfrom
onmete:fix/ols-3223-advisory-approval-creation

Conversation

@onmete
Copy link
Copy Markdown
Contributor

@onmete onmete commented Jun 3, 2026

Summary

  • Fix ensureProposalApproval crashing on analysis-only proposals when the ApprovalPolicy auto-approves Verification or Execution stages
  • Skip auto-stage seeding for steps the proposal doesn't define (IsZero() guard)
  • Update behavioral spec (.ai/spec/what/approval.md rule 2) to clarify absent steps must not be seeded

Root Cause

The auto-stage loop iterated over all Automatic policy stages unconditionally. For analysis-only proposals, proposal.Spec.Verification is zero-value — producing a VerificationApproval{Agent: ""} that serializes as an empty struct, which the CEL discriminated-union validation rejects.

Testing

  • make vet — pass
  • make api-lint — pass
  • make test — pass (all unit + state machine tests)
  • New unit test: TestEnsureProposalApproval_AnalysisOnly_SkipsAbsentStages
  • New state machine test: TestAutoApproval_AdvisoryOnly_SkipsAbsentStages

Spec

  • Updated: .ai/spec/what/approval.md (rule 2 — seeding constraint for absent steps)

Made with Cursor

Summary by CodeRabbit

  • Bug Fixes

    • Fixed approval workflow generation to exclude stages when the proposal doesn't include those capability blocks.
  • Tests

    • Added test coverage for analysis-only and advisory-only proposal scenarios.
  • Documentation

    • Updated behavioral specification for ProposalApproval resource initialization.

@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 3, 2026
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Jun 3, 2026

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

Details

In response to this:

Summary

  • Fix ensureProposalApproval crashing on analysis-only proposals when the ApprovalPolicy auto-approves Verification or Execution stages
  • Skip auto-stage seeding for steps the proposal doesn't define (IsZero() guard)
  • Update behavioral spec (.ai/spec/what/approval.md rule 2) to clarify absent steps must not be seeded

Root Cause

The auto-stage loop iterated over all Automatic policy stages unconditionally. For analysis-only proposals, proposal.Spec.Verification is zero-value — producing a VerificationApproval{Agent: ""} that serializes as an empty struct, which the CEL discriminated-union validation rejects.

Testing

  • make vet — pass
  • make api-lint — pass
  • make test — pass (all unit + state machine tests)
  • New unit test: TestEnsureProposalApproval_AnalysisOnly_SkipsAbsentStages
  • New state machine test: TestAutoApproval_AdvisoryOnly_SkipsAbsentStages

Spec

  • Updated: .ai/spec/what/approval.md (rule 2 — seeding constraint for absent steps)

Made with Cursor

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.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 3, 2026

Warning

Review limit reached

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

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

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ 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: 4e725927-fa31-4c69-b30f-c2932ce8e1c1

📥 Commits

Reviewing files that changed from the base of the PR and between cb68eda and 1614dde.

📒 Files selected for processing (4)
  • .ai/spec/what/approval.md
  • controller/proposal/approval.go
  • controller/proposal/approval_test.go
  • controller/proposal/state_machine_test.go
📝 Walkthrough

Walkthrough

The PR conditionally skips seeding approval stages for workflow steps that a Proposal does not define, preventing invalid stage entries. The specification is clarified, the approval seeding logic implements guards for absent steps, and two tests validate the behavior at unit and integration levels.

Changes

Conditional approval stage seeding

Layer / File(s) Summary
Specification and approval stage seeding logic
.ai/spec/what/approval.md, controller/proposal/approval.go
The behavioral spec clarifies that ProposalApproval.spec.stages must only include Automatic stages the Proposal defines. ensureProposalApproval now guards against creating SandboxStepExecution and SandboxStepVerification approval stages when the proposal has unset Execution or Verification blocks.
Test coverage for conditional stage seeding
controller/proposal/approval_test.go, controller/proposal/state_machine_test.go
Unit test validates ensureProposalApproval creates only Analysis stage for analysis-only proposals, excluding Verification and Execution stages. Integration test confirms auto-approval workflow for advisory-only proposals produces ProposalApproval without Verification stage and reaches ProposalPhaseCompleted.

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing ProposalApproval creation for analysis-only proposals by skipping absent stages.
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.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@openshift-ci openshift-ci Bot requested review from blublinsky and joshuawilson June 3, 2026 17:29
@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented Jun 3, 2026

[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 xrajesh 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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

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

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

60-75: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix Analysis/Escalation auto-stage seeding when the proposal agent is empty (and drop redundant Escalation seeding for automatic policies)

  • controller/proposal/approval.go seeds stage.Analysis = AnalysisApproval{Agent: proposal.Spec.Analysis.Agent} unconditionally and seeds stage.Escalation = EscalationApproval{Agent: proposal.Spec.Analysis.Agent} for SandboxStepEscalation automatic policies; there’s no IsZero() guard for either path.
  • Proposal.spec has no escalation field (so escalation can’t be “defined” by the proposal), and for escalation handling the reconciler defaults to resolved.Analysis unless an escalation stage override exists; isStageApproved() already auto-approves via the policy when the stage entry is absent. So seeding an Escalation stage for Automatic is redundant.
  • Empty-agent risk is still real: ApprovalStage discriminated-union validation requires has(self.analysis) / has(self.escalation) when type matches, but analysis/escalation are json:",omitzero". If proposal.Spec.Analysis.Agent is omitted/empty, the seeded AnalysisApproval{Agent: ""} / EscalationApproval{Agent: ""} becomes the zero struct and causes the entire analysis/escalation field to be omitted—reintroducing the same validation failure path you guarded for Execution/Verification. ProposalStep.Agent is optional (no CRD default annotation for ProposalStep.Agent), so non-empty is not guaranteed.
🤖 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/approval.go` around lines 60 - 75, The code seeds
stage.Analysis and stage.Escalation unconditionally which can produce zero-value
structs (empty Agent) and reintroduce validation failures; update the switch in
controller/proposal/approval.go so that for SandboxStepAnalysis you only set
stage.Analysis when proposal.Spec.Analysis.IsZero() is false (or
proposal.Spec.Analysis.Agent is non-empty), for SandboxStepExecution and
SandboxStepVerification keep the existing IsZero guards, and remove the
automatic seeding of stage.Escalation entirely for SandboxStepEscalation (do not
set EscalationApproval using proposal.Spec.Analysis.Agent); this ensures you
only create non-empty Analysis/Execution/Verification entries and avoid
redundant Escalation seeding for automatic policies.
🤖 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.

Outside diff comments:
In `@controller/proposal/approval.go`:
- Around line 60-75: The code seeds stage.Analysis and stage.Escalation
unconditionally which can produce zero-value structs (empty Agent) and
reintroduce validation failures; update the switch in
controller/proposal/approval.go so that for SandboxStepAnalysis you only set
stage.Analysis when proposal.Spec.Analysis.IsZero() is false (or
proposal.Spec.Analysis.Agent is non-empty), for SandboxStepExecution and
SandboxStepVerification keep the existing IsZero guards, and remove the
automatic seeding of stage.Escalation entirely for SandboxStepEscalation (do not
set EscalationApproval using proposal.Spec.Analysis.Agent); this ensures you
only create non-empty Analysis/Execution/Verification entries and avoid
redundant Escalation seeding for automatic policies.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 02a86769-5a92-4b57-94ed-b51ff5cb1f13

📥 Commits

Reviewing files that changed from the base of the PR and between eed7142 and cb68eda.

📒 Files selected for processing (4)
  • .ai/spec/what/approval.md
  • controller/proposal/approval.go
  • controller/proposal/approval_test.go
  • controller/proposal/state_machine_test.go

…ages (OLS-3223)

When the ApprovalPolicy auto-approves Verification or Execution but the
proposal is analysis-only (or has no verification), the controller tried
to create an ApprovalStage with an empty agent. The zero-value struct
was omitted by omitzero serialization, causing the CEL discriminated-union
validation to reject the Create call. The reconciler retried indefinitely.

Fix: check ProposalStep.IsZero() before building auto-stage entries,
aligning with the same guards resolveProposal() already uses.

Co-authored-by: Cursor <cursoragent@cursor.com>
@onmete onmete force-pushed the fix/ols-3223-advisory-approval-creation branch from cb68eda to 1614dde Compare June 3, 2026 17:51
@onmete
Copy link
Copy Markdown
Contributor Author

onmete commented Jun 3, 2026

Re: CodeRabbit review — Analysis/Escalation empty-agent risk:

Fixed in 1614dde:

  • Analysis: now uses stepAgentName() (returns "default" when Agent is empty) instead of raw proposal.Spec.Analysis.Agent, ensuring the seeded AnalysisApproval is never zero-value.
  • Execution/Verification: same stepAgentName() treatment for consistency.
  • Escalation: removed auto-seeding entirely — Proposal.spec has no escalation field, and isStageApproved() already handles escalation via the policy fallback path. Seeding it was redundant and carried the empty-agent risk.

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented Jun 3, 2026

@onmete: 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