OLS-3267: spec: AgenticOLSConfig status conditions for suspension observability#161
OLS-3267: spec: AgenticOLSConfig status conditions for suspension observability#161onmete wants to merge 1 commit into
Conversation
…observability Add behavioral rules for suspension lifecycle visibility: - Status subresource with Suspended condition and lastTransitionTime - Kubernetes Events on suspension activation/deactivation - RBAC requirements for status updates - Planned changes for admission-time blocking and sandbox isolation Co-authored-by: Cursor <cursoragent@cursor.com>
|
@onmete: This pull request references OLS-3267 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. DetailsIn response to this:
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. |
📝 WalkthroughSummary by CodeRabbit
WalkthroughTwo spec documents for the ChangesAgenticOLSConfig Kill Switch Spec
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.ai/spec/what/crd-api.md (1)
45-46:⚠️ Potential issue | 🔴 CriticalRule 45 inherits API type contract break from system-config.md.
Rule 45 references system-config.md rules 5a–5e, which specify a
/statussubresource withSuspendedcondition. The CRD type definition (api/v1alpha1/agenticolsconfig_types.go) lacks aStatusfield; this must be added before rule 45 can be implemented.Rule 46 (RBAC requirements) is correct: the operator service account needs
get,update, andpatchpermissions onagenticolsconfigs/status. Verify that the operator's RBAC binding includes these subresource permissions.🤖 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 @.ai/spec/what/crd-api.md around lines 45 - 46, The CRD type definition in the file `api/v1alpha1/agenticolsconfig_types.go` is missing a required Status field to support the `/status` subresource with a Suspended condition as specified in system-config.md rules 5a-5e. Add a Status field to the AgenticolsConfig type that includes a Suspended condition following the standard Kubernetes condition pattern. Additionally, verify that the operator's RBAC configuration includes the necessary get, update, and patch permissions on the agenticolsconfigs/status subresource to allow the operator service account to modify the status.
🤖 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/what/system-config.md:
- Line 32: Rule 5d in the AgenticOLSConfig specification requires emitting
Kubernetes Events with SuspensionActivated and SuspensionDeactivated reasons
that include counts of affected proposals and sandbox pods, but lacks a standard
message format definition. Update Rule 5d to specify the exact message format
template for both suspension activation and deactivation events, including
concrete examples that show how to consistently format the count information so
that all implementations produce uniform event messages regardless of the actual
numbers involved.
- Around line 29-34: The AgenticOLSConfig type definition in
api/v1alpha1/agenticolsconfig_types.go is missing the Status field required to
implement the /status subresource specified in rules 5a–5e. Add a new
AgenticOLSConfigStatus struct type that contains a Conditions field of type
slice of metav1.Condition, then add a Status field of type
AgenticOLSConfigStatus to the AgenticOLSConfig struct with appropriate JSON tags
to enable the /status subresource and allow the operator to update suspension
conditions.
- Line 33: The specification document rules 5a-5e require a `Suspended`
condition in the `AgenticOLSConfig` status subresource, but this is not yet
implemented in the CRD (api/v1alpha1/agenticolsconfig_types.go). To resolve
this, you must choose one of two approaches: either implement a dedicated
`AgenticOLSConfig` controller that centralizes the logic to iterate through all
non-terminal proposals, emergency-stop them, and atomically patch the
`Suspended` condition with an accurate proposal count before proceeding; or
update the specification (rules 5a-5e) to relax rule 5e and explicitly allow
eventual consistency, documenting that the condition and proposal count will be
updated after all non-terminal proposals have been individually processed by the
existing proposal reconciler rather than in a single atomic operation.
---
Outside diff comments:
In @.ai/spec/what/crd-api.md:
- Around line 45-46: The CRD type definition in the file
`api/v1alpha1/agenticolsconfig_types.go` is missing a required Status field to
support the `/status` subresource with a Suspended condition as specified in
system-config.md rules 5a-5e. Add a Status field to the AgenticolsConfig type
that includes a Suspended condition following the standard Kubernetes condition
pattern. Additionally, verify that the operator's RBAC configuration includes
the necessary get, update, and patch permissions on the agenticolsconfigs/status
subresource to allow the operator service account to modify the status.
🪄 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: 7bade234-2201-43b1-9b5d-f8048112be6b
📒 Files selected for processing (2)
.ai/spec/what/crd-api.md.ai/spec/what/system-config.md
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
openshift/lightspeed-agentic-sandbox(manual)
| 5a. **Status subresource**: `AgenticOLSConfig` MUST have a `/status` subresource. The status MUST include a `conditions` array following the standard `metav1.Condition` shape. | ||
| 5b. **Suspended condition**: When `spec.suspended` is set to `true` and the operator has processed the suspension, the operator MUST set condition type `Suspended` with status `True`, reason `AdminActivated`, and `lastTransitionTime` reflecting when suspension was activated. The message SHOULD include the count of proposals emergency-stopped (e.g., `"System suspended; 12 proposals emergency-stopped"`). | ||
| 5c. **Suspended condition on deactivation**: When `spec.suspended` is set back to `false`, the operator MUST update the `Suspended` condition to status `False`, reason `AdminDeactivated`, preserving the new `lastTransitionTime`. | ||
| 5d. **Suspension Events**: The operator MUST emit a Kubernetes Event on the `AgenticOLSConfig` object when suspension is activated (reason `SuspensionActivated`, message includes count of affected proposals and sandbox pods) and when suspension is deactivated (reason `SuspensionDeactivated`). Events use `type: Warning` for activation and `type: Normal` for deactivation. | ||
| 5e. **Status update timing**: The `Suspended` condition and activation Event MUST be set after all non-terminal proposals have been emergency-stopped (not before), so the condition's message reflects the final count. | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find the agenticolsconfig_types.go file
find . -name "agenticolsconfig_types.go" -type fRepository: openshift/lightspeed-agentic-operator
Length of output: 122
🏁 Script executed:
#!/bin/bash
# Find the spec file mentioned in the review
find . -path "*/.ai/spec/what/system-config.md" -type fRepository: openshift/lightspeed-agentic-operator
Length of output: 114
🏁 Script executed:
#!/bin/bash
# List API directory structure
fd "api/v1" --type dRepository: openshift/lightspeed-agentic-operator
Length of output: 63
🏁 Script executed:
#!/bin/bash
# Read the agenticolsconfig_types.go file
cat -n ./api/v1alpha1/agenticolsconfig_types.goRepository: openshift/lightspeed-agentic-operator
Length of output: 3519
🏁 Script executed:
#!/bin/bash
# Read the spec file, focusing on the rules mentioned (lines 27-34 based on review)
sed -n '25,40p' ./.ai/spec/what/system-config.mdRepository: openshift/lightspeed-agentic-operator
Length of output: 2765
API type definition missing Status field — rules 5a–5e cannot be implemented.
Rules 5a–5e specify a /status subresource with a Suspended condition type on AgenticOLSConfig. However, the CRD type definition in api/v1alpha1/agenticolsconfig_types.go currently has only TypeMeta, ObjectMeta, and Spec fields; the Status field is absent. Kubernetes requires the type definition to include the Status field to serve the /status subresource. Add:
type AgenticOLSConfigStatus struct {
Conditions []metav1.Condition `json:"conditions,omitempty"`
}And add the field to AgenticOLSConfig:
Status AgenticOLSConfigStatus `json:"status,omitempty"`🤖 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 @.ai/spec/what/system-config.md around lines 29 - 34, The AgenticOLSConfig
type definition in api/v1alpha1/agenticolsconfig_types.go is missing the Status
field required to implement the /status subresource specified in rules 5a–5e.
Add a new AgenticOLSConfigStatus struct type that contains a Conditions field of
type slice of metav1.Condition, then add a Status field of type
AgenticOLSConfigStatus to the AgenticOLSConfig struct with appropriate JSON tags
to enable the /status subresource and allow the operator to update suspension
conditions.
| 5a. **Status subresource**: `AgenticOLSConfig` MUST have a `/status` subresource. The status MUST include a `conditions` array following the standard `metav1.Condition` shape. | ||
| 5b. **Suspended condition**: When `spec.suspended` is set to `true` and the operator has processed the suspension, the operator MUST set condition type `Suspended` with status `True`, reason `AdminActivated`, and `lastTransitionTime` reflecting when suspension was activated. The message SHOULD include the count of proposals emergency-stopped (e.g., `"System suspended; 12 proposals emergency-stopped"`). | ||
| 5c. **Suspended condition on deactivation**: When `spec.suspended` is set back to `false`, the operator MUST update the `Suspended` condition to status `False`, reason `AdminDeactivated`, preserving the new `lastTransitionTime`. | ||
| 5d. **Suspension Events**: The operator MUST emit a Kubernetes Event on the `AgenticOLSConfig` object when suspension is activated (reason `SuspensionActivated`, message includes count of affected proposals and sandbox pods) and when suspension is deactivated (reason `SuspensionDeactivated`). Events use `type: Warning` for activation and `type: Normal` for deactivation. |
There was a problem hiding this comment.
Rule 5d: Specify exact event message format for suspension activation/deactivation.
Rule 5d requires Events to include "count of affected proposals and sandbox pods" but does not specify the exact message format. Implementers may produce inconsistent formats: e.g., "System suspended; 12 proposals, 24 pods" vs "12 proposals emergency-stopped; 24 sandbox pods". Define a standard format template to ensure observability consistency.
Example:
- Activation:
"System suspended; 12 proposals emergency-stopped, 24 sandbox pods released" - Deactivation:
"System resumed; agentic operations re-enabled"
🤖 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 @.ai/spec/what/system-config.md at line 32, Rule 5d in the AgenticOLSConfig
specification requires emitting Kubernetes Events with SuspensionActivated and
SuspensionDeactivated reasons that include counts of affected proposals and
sandbox pods, but lacks a standard message format definition. Update Rule 5d to
specify the exact message format template for both suspension activation and
deactivation events, including concrete examples that show how to consistently
format the count information so that all implementations produce uniform event
messages regardless of the actual numbers involved.
| 5b. **Suspended condition**: When `spec.suspended` is set to `true` and the operator has processed the suspension, the operator MUST set condition type `Suspended` with status `True`, reason `AdminActivated`, and `lastTransitionTime` reflecting when suspension was activated. The message SHOULD include the count of proposals emergency-stopped (e.g., `"System suspended; 12 proposals emergency-stopped"`). | ||
| 5c. **Suspended condition on deactivation**: When `spec.suspended` is set back to `false`, the operator MUST update the `Suspended` condition to status `False`, reason `AdminDeactivated`, preserving the new `lastTransitionTime`. | ||
| 5d. **Suspension Events**: The operator MUST emit a Kubernetes Event on the `AgenticOLSConfig` object when suspension is activated (reason `SuspensionActivated`, message includes count of affected proposals and sandbox pods) and when suspension is deactivated (reason `SuspensionDeactivated`). Events use `type: Warning` for activation and `type: Normal` for deactivation. | ||
| 5e. **Status update timing**: The `Suspended` condition and activation Event MUST be set after all non-terminal proposals have been emergency-stopped (not before), so the condition's message reflects the final count. |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Read the specification file to understand rule 5e in context
cat -n .ai/spec/what/system-config.md | head -50Repository: openshift/lightspeed-agentic-operator
Length of output: 6709
🏁 Script executed:
#!/bin/bash
# Search for rules 12-14 mentioned in the comment
grep -n "12\|13\|14\|Rule 12\|Rule 13\|Rule 14" .ai/spec/what/system-config.mdRepository: openshift/lightspeed-agentic-operator
Length of output: 1241
🏁 Script executed:
#!/bin/bash
# Find reconciler implementation files
find . -type f -name "*reconcil*.go" -o -name "*controller*.go" | head -20Repository: openshift/lightspeed-agentic-operator
Length of output: 233
🏁 Script executed:
#!/bin/bash
# Read the proposal reconciler to understand suspension handling
wc -l ./controller/proposal/reconciler.goRepository: openshift/lightspeed-agentic-operator
Length of output: 121
🏁 Script executed:
#!/bin/bash
# Search for suspension-related code in proposal reconciler
grep -n "Suspended\|suspended\|EmergencyStopped\|5e\|status update" ./controller/proposal/reconciler.go | head -30Repository: openshift/lightspeed-agentic-operator
Length of output: 202
🏁 Script executed:
#!/bin/bash
# Find the AgenticOLSConfig controller
find . -type f -name "*.go" | xargs grep -l "AgenticOLSConfig" | grep -i "controller\|reconcil"Repository: openshift/lightspeed-agentic-operator
Length of output: 263
🏁 Script executed:
#!/bin/bash
# Read the proposal reconciler suspension logic
sed -n '75,120p' ./controller/proposal/reconciler.goRepository: openshift/lightspeed-agentic-operator
Length of output: 1390
🏁 Script executed:
#!/bin/bash
# Search for isSuspended function implementation
grep -n "func isSuspended\|func.*Suspended" ./controller/proposal/helpers.goRepository: openshift/lightspeed-agentic-operator
Length of output: 155
🏁 Script executed:
#!/bin/bash
# Search for where Suspended condition is set on AgenticOLSConfig
grep -rn "Suspended.*condition\|condition.*Suspended" ./controller/ | grep -v "EmergencyStopped"Repository: openshift/lightspeed-agentic-operator
Length of output: 63
🏁 Script executed:
#!/bin/bash
# Find all files related to AgenticOLSConfig controller
find . -type f -name "*.go" | xargs grep -l "AgenticOLSConfig.*Reconciler\|type.*Reconciler.*struct" | head -10Repository: openshift/lightspeed-agentic-operator
Length of output: 117
🏁 Script executed:
#!/bin/bash
# Read isSuspended function implementation
sed -n '64,90p' ./controller/proposal/helpers.goRepository: openshift/lightspeed-agentic-operator
Length of output: 1270
🏁 Script executed:
#!/bin/bash
# Search for handleSuspension implementation
grep -n "func.*handleSuspension" ./controller/proposal/reconciler.goRepository: openshift/lightspeed-agentic-operator
Length of output: 63
🏁 Script executed:
#!/bin/bash
# List the main controller structure
ls -la ./controller/Repository: openshift/lightspeed-agentic-operator
Length of output: 428
🏁 Script executed:
#!/bin/bash
# Search for config controller
find ./controller -type d -name "*config*"Repository: openshift/lightspeed-agentic-operator
Length of output: 63
🏁 Script executed:
#!/bin/bash
# Search for handleSuspension in all go files
grep -rn "handleSuspension" ./controller/Repository: openshift/lightspeed-agentic-operator
Length of output: 456
🏁 Script executed:
#!/bin/bash
# Search for where Suspended condition is set/patched
grep -rn "type.*Suspended\|reason.*Suspended\|Suspended.*status\|Suspended.*condition" ./controller/Repository: openshift/lightspeed-agentic-operator
Length of output: 532
🏁 Script executed:
#!/bin/bash
# Read more of the proposal reconciler to find handleSuspension
sed -n '120,180p' ./controller/proposal/reconciler.goRepository: openshift/lightspeed-agentic-operator
Length of output: 2158
🏁 Script executed:
#!/bin/bash
# List all go files in controller to find the config controller
find ./controller -name "*.go" -type f | sortRepository: openshift/lightspeed-agentic-operator
Length of output: 1427
🏁 Script executed:
#!/bin/bash
# Read handleSuspension implementation
sed -n '490,550p' ./controller/proposal/handlers.goRepository: openshift/lightspeed-agentic-operator
Length of output: 2239
🏁 Script executed:
#!/bin/bash
# Search for where AgenticOLSConfig status is patched
grep -rn "status.*patch\|status.*update\|Patch.*Suspended\|Update.*Suspended" ./controller/ | grep -i "config\|agentic"Repository: openshift/lightspeed-agentic-operator
Length of output: 585
🏁 Script executed:
#!/bin/bash
# Search more broadly for AgenticOLSConfig status updates
grep -rn "AgenticOLSConfig" ./controller/setup.goRepository: openshift/lightspeed-agentic-operator
Length of output: 63
🏁 Script executed:
#!/bin/bash
# Check if there's an AgenticOLSConfig controller in main or elsewhere
find . -name "*.go" -type f | xargs grep -l "AgenticOLSConfig.*Reconciler\|func.*SetupWithManager"Repository: openshift/lightspeed-agentic-operator
Length of output: 117
🏁 Script executed:
#!/bin/bash
# Search for where Suspended condition is set on AgenticOLSConfig
grep -rn "\.Status\.Conditions" ./controller/ | grep -i "config\|suspended"Repository: openshift/lightspeed-agentic-operator
Length of output: 63
🏁 Script executed:
#!/bin/bash
# Read setup.go to see if there's an AgenticOLSConfig controller registered
cat ./controller/setup.goRepository: openshift/lightspeed-agentic-operator
Length of output: 2307
🏁 Script executed:
#!/bin/bash
# Search for main.go or cmd files
find . -name "main.go" -type f | head -5Repository: openshift/lightspeed-agentic-operator
Length of output: 177
🏁 Script executed:
#!/bin/bash
# Look for AgenticOLSConfig controller setup
grep -rn "AgenticOLSConfig" ./controller/setup.goRepository: openshift/lightspeed-agentic-operator
Length of output: 63
🏁 Script executed:
#!/bin/bash
# Search broadly for where Suspended condition is updated on AgenticOLSConfig
grep -rn "Suspended.*AdminActivated\|AdminActivated.*Suspended" ./Repository: openshift/lightspeed-agentic-operator
Length of output: 523
🏁 Script executed:
#!/bin/bash
# Search for any condition patches on config objects
grep -rn "config\.Status\.Conditions\|SetStatusCondition.*config" ./controller/Repository: openshift/lightspeed-agentic-operator
Length of output: 63
🏁 Script executed:
#!/bin/bash
# Check if there's a separate reconciler for AgenticOLSConfig
find . -type f -name "*.go" | xargs grep -l "type.*Config.*Reconciler\|AgenticOLSConfig.*Reconcile"Repository: openshift/lightspeed-agentic-operator
Length of output: 65
🏁 Script executed:
#!/bin/bash
# Check the API/CRD definitions to understand what's expected
find . -path "*/api/*" -name "*config*" -type f | head -10Repository: openshift/lightspeed-agentic-operator
Length of output: 122
🏁 Script executed:
#!/bin/bash
# Read the AgenticOLSConfig API types
cat ./api/v1alpha1/agenticolsconfig_types.goRepository: openshift/lightspeed-agentic-operator
Length of output: 2945
🏁 Script executed:
#!/bin/bash
# Search for any reconciler that watches AgenticOLSConfig
grep -rn "SetupWithManager\|Watches.*AgenticOLSConfig" ./controller/proposal/Repository: openshift/lightspeed-agentic-operator
Length of output: 510
🏁 Script executed:
#!/bin/bash
# Check SetupWithManager in proposal reconciler
grep -A 20 "SetupWithManager" ./controller/proposal/reconciler.goRepository: openshift/lightspeed-agentic-operator
Length of output: 2779
🏁 Script executed:
#!/bin/bash
# Read the full SetupWithManager to see the AgenticOLSConfig watch
sed -n '182,230p' ./controller/proposal/reconciler.goRepository: openshift/lightspeed-agentic-operator
Length of output: 1956
🏁 Script executed:
#!/bin/bash
# Check if AgenticOLSConfig has a status subresource defined
grep -A 30 "type AgenticOLSConfig struct" ./api/v1alpha1/agenticolsconfig_types.go | tail -20Repository: openshift/lightspeed-agentic-operator
Length of output: 610
🏁 Script executed:
#!/bin/bash
# Search for Status in the config types file
grep -n "Status\|Conditions" ./api/v1alpha1/agenticolsconfig_types.goRepository: openshift/lightspeed-agentic-operator
Length of output: 63
🏁 Script executed:
#!/bin/bash
# Get the complete agenticolsconfig_types.go file to confirm
wc -l ./api/v1alpha1/agenticolsconfig_types.goRepository: openshift/lightspeed-agentic-operator
Length of output: 125
🏁 Script executed:
#!/bin/bash
# Read the entire file to see if Status is defined anywhere
cat ./api/v1alpha1/agenticolsconfig_types.goRepository: openshift/lightspeed-agentic-operator
Length of output: 2945
🏁 Script executed:
#!/bin/bash
# Check spec files for AgenticOLSConfig to understand what's actually implemented
find ./.ai/spec -name "*.md" | xargs grep -l "AgenticOLSConfig\|Suspended condition"Repository: openshift/lightspeed-agentic-operator
Length of output: 192
🏁 Script executed:
#!/bin/bash
# Check the reconciler tests for how suspension is tested
grep -A 20 "handleSuspension\|Suspended" ./controller/proposal/reconciler_test.go | head -60Repository: openshift/lightspeed-agentic-operator
Length of output: 1887
🏁 Script executed:
#!/bin/bash
# Search for any TODO or FIXME related to Suspended condition on AgenticOLSConfig
grep -rn "TODO\|FIXME\|XXX" ./controller/proposal/ | grep -i "suspended\|status\|config"Repository: openshift/lightspeed-agentic-operator
Length of output: 63
🏁 Script executed:
#!/bin/bash
# Check if there's a separate AgenticOLSConfig reconciler mentioned anywhere
find . -name "*.go" | xargs grep -l "AgenticOLSConfig.*Reconciler\|type.*Reconciler" | xargs grep -l "SetupWithManager"Repository: openshift/lightspeed-agentic-operator
Length of output: 117
🏁 Script executed:
#!/bin/bash
# Search comprehensively for any Status struct on AgenticOLSConfig
find . -name "*.go" | xargs grep -A 50 "AgenticOLSConfigStatus\|type.*Config.*Status"Repository: openshift/lightspeed-agentic-operator
Length of output: 65
🏁 Script executed:
#!/bin/bash
# Check all kubebuilder directives in agenticolsconfig_types.go
grep -n "kubebuilder" ./api/v1alpha1/agenticolsconfig_types.goRepository: openshift/lightspeed-agentic-operator
Length of output: 564
🏁 Script executed:
#!/bin/bash
# Look for any code that patches AgenticOLSConfig status
grep -rn "AgenticOLSConfig.*Patch\|Patch.*AgenticOLSConfig\|\.Status\.Patch" ./Repository: openshift/lightspeed-agentic-operator
Length of output: 63
🏁 Script executed:
#!/bin/bash
# Check if there are any integration tests that verify rule 5e
grep -rn "AdminActivated\|Suspended.*condition\|rule 5e\|5e.*timing" ./Repository: openshift/lightspeed-agentic-operator
Length of output: 1622
🏁 Script executed:
#!/bin/bash
# Check the reconciler spec for more details on suspension status tracking
cat ./.ai/spec/what/crd-api.md | grep -A 10 -B 5 "PLANNED.*OLS-3267"Repository: openshift/lightspeed-agentic-operator
Length of output: 598
🏁 Script executed:
#!/bin/bash
# Check reconciler.md for implementation guidance
cat ./.ai/spec/how/reconciler.md | grep -A 20 "Suspension check"Repository: openshift/lightspeed-agentic-operator
Length of output: 2768
AgenticOLSConfig status subresource and Suspended condition (rules 5a–5e) are not yet implemented.
Rules 5a–5e require AgenticOLSConfig to have a /status subresource with a Suspended condition (status True, reason AdminActivated, message with proposal count) set after all non-terminal proposals have been emergency-stopped. However:
- The
AgenticOLSConfigCRD (api/v1alpha1/agenticolsconfig_types.go) has no status subresource — only spec. - The specification itself marks this feature
[PLANNED: OLS-3267]in crd-api.md. - The proposal reconciler processes proposals individually as they are re-queued; there is no centralized completion-tracking mechanism or separate
AgenticOLSConfigcontroller to coordinate the status update.
The current architecture cannot atomically set the Suspended condition with an accurate proposal count because no single reconciler owns that decision — each proposal reconciliation is independent. Resolve this by either:
- Implementing a dedicated
AgenticOLSConfigcontroller that iterates all non-terminal proposals, terminates them, and then patches theSuspendedcondition once, or - Relax rule 5e to allow eventual consistency: update the condition once all non-terminal proposals have been processed, accepting that the count may not reflect true concurrency.
🤖 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 @.ai/spec/what/system-config.md at line 33, The specification document rules
5a-5e require a `Suspended` condition in the `AgenticOLSConfig` status
subresource, but this is not yet implemented in the CRD
(api/v1alpha1/agenticolsconfig_types.go). To resolve this, you must choose one
of two approaches: either implement a dedicated `AgenticOLSConfig` controller
that centralizes the logic to iterate through all non-terminal proposals,
emergency-stop them, and atomically patch the `Suspended` condition with an
accurate proposal count before proceeding; or update the specification (rules
5a-5e) to relax rule 5e and explicitly allow eventual consistency, documenting
that the condition and proposal count will be updated after all non-terminal
proposals have been individually processed by the existing proposal reconciler
rather than in a single atomic operation.
Summary
AgenticOLSConfigstatus subresource with aSuspendedcondition tracking suspension lifecycle (lastTransitionTime, activation/deactivation reasons)Design Decisions
From refinement session:
metav1.ConditionwithSuspendedtype + Events. Typed summary fields (e.g.,emergencyStoppedCount) deferred as YAGNI — Prometheus metrics are a better fit if dashboarding is needed later.paramRefper spike OLS-3166. VAP/binding lifecycle ownership deferred to OLS-3302.Test plan
system-config.mdare consistent with existing rules 1–15Made with Cursor