v1alpha1

package
v0.0.1-dev.20260520 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package v1alpha1 contains API Schema definitions for the agentic v1alpha1 API group +kubebuilder:object:generate=true +groupName=agentic.openshift.io

Index

Constants

View Source
const (
	ReasonRetryingExecution = "RetryingExecution"
	ReasonRetriesExhausted  = "RetriesExhausted"
)

Condition reasons used by DerivePhase for state transitions. SYNC: must match derivePhaseFromConditions in lightspeed-agentic-console/src/models/proposal.ts

View Source
const (
	// ProposalConditionAnalyzed indicates whether analysis has completed.
	// Status=True when analysis succeeds, Status=False on failure,
	// Status=Unknown while analysis is in progress.
	ProposalConditionAnalyzed string = "Analyzed"
	// ProposalConditionExecuted indicates whether execution has completed.
	// Status=True when execution succeeds, Status=False on failure,
	// Status=Unknown while execution is in progress.
	ProposalConditionExecuted string = "Executed"
	// ProposalConditionVerified indicates whether verification has passed.
	// Status=True when verification succeeds, Status=False on failure,
	// Status=Unknown while verification is in progress.
	ProposalConditionVerified string = "Verified"
	// ProposalConditionDenied indicates the user denied a step on the
	// ProposalApproval resource. Status=True when denied (terminal).
	ProposalConditionDenied string = "Denied"
	// ProposalConditionEscalated indicates escalation state. Status=Unknown
	// while escalation is pending approval or in progress, Status=True when
	// escalation completes (terminal), Status=False on escalation failure.
	ProposalConditionEscalated string = "Escalated"
)

Condition types for Proposal. Conditions are the primary mechanism for observing proposal state. The operator sets these as the proposal progresses through its lifecycle. Each condition has a type, status (True/False/Unknown), reason (CamelCase token), and message.

The lifecycle is derived from the combination of conditions:

No conditions       -> just created, pending
Analyzed=Unknown    -> analysis in progress
Analyzed=True       -> analysis complete, next step queued
Executed=Unknown    -> execution in progress
Executed=True       -> execution complete
Verified=Unknown    -> verification in progress
Verified=True       -> verification passed (terminal: success)
Denied=True         -> user denied a step (terminal)
Escalated=True      -> max retries exhausted (terminal)
Any condition=False -> step failed; check reason and message
View Source
const (
	ResultConditionStarted   = "Started"
	ResultConditionCompleted = "Completed"

	ResultReasonStepStarted = "StepStarted"
	ResultReasonSucceeded   = "Succeeded"
	ResultReasonFailed      = "Failed"
)
View Source
const (
	// AgentConditionReady indicates whether all referenced resources
	// (LLMProvider, Secrets) exist and are accessible.
	AgentConditionReady string = "Ready"
)
View Source
const DefaultMaxConcurrentProposals int32 = 5

Variables

View Source
var (
	// GroupVersion is group version used to register these objects
	GroupVersion = schema.GroupVersion{Group: "agentic.openshift.io", Version: "v1alpha1"}

	// SchemeBuilder is used to add go types to the GroupVersionKind scheme
	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

	// AddToScheme adds the types in this group-version to the given scheme.
	AddToScheme = SchemeBuilder.AddToScheme
)

Functions

This section is empty.

Types

type AWSBedrockConfig

type AWSBedrockConfig struct {
	// credentialsSecret references a Secret in the operator namespace
	// (openshift-lightspeed) containing AWS credentials. The Secret must
	// contain the keys AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
	// +required
	CredentialsSecret SecretReference `json:"credentialsSecret,omitzero"`

	// region is the AWS region for the Bedrock endpoint.
	// Must begin with a lowercase letter and end with a lowercase
	// alphanumeric character. May contain lowercase letters, digits,
	// and hyphens (e.g., "us-east-1", "eu-west-2", "ap-southeast-1").
	// +required
	// +kubebuilder:validation:MinLength=2
	// +kubebuilder:validation:MaxLength=63
	// +kubebuilder:validation:XValidation:rule="self.matches('^[a-z][a-z0-9-]*[a-z0-9]$')",message="region must contain only lowercase letters, digits, and hyphens, start with a letter, and not end with a hyphen"
	Region string `json:"region,omitempty"`

	// url is an optional override for the AWS Bedrock API endpoint.
	// Only needed for custom deployments or API proxies.
	// Must be a valid HTTP or HTTPS URL with a hostname. Paths and query
	// parameters are allowed. Fragments and userinfo are not permitted.
	// Maximum 2048 characters.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=2048
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getScheme() in ['http', 'https']",message="must use http or https scheme"
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getHostname() != ”",message="must include a hostname"
	// +kubebuilder:validation:XValidation:rule="!self.contains('@')",message="userinfo is not allowed in URL"
	// +kubebuilder:validation:XValidation:rule="!self.contains('#')",message="fragments are not allowed in URL"
	URL string `json:"url,omitempty"`
}

AWSBedrockConfig contains configuration for the AWS Bedrock provider.

func (*AWSBedrockConfig) DeepCopy

func (in *AWSBedrockConfig) DeepCopy() *AWSBedrockConfig

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSBedrockConfig.

func (*AWSBedrockConfig) DeepCopyInto

func (in *AWSBedrockConfig) DeepCopyInto(out *AWSBedrockConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ActionOutcome

type ActionOutcome string

ActionOutcome indicates whether an individual execution action succeeded. +kubebuilder:validation:Enum=Succeeded;Failed

const (
	ActionOutcomeSucceeded ActionOutcome = "Succeeded"
	ActionOutcomeFailed    ActionOutcome = "Failed"
)

func ActionOutcomeFromBool

func ActionOutcomeFromBool(success bool) ActionOutcome

type Agent

type Agent struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is the standard object metadata.
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty"`

	// spec defines the desired state of Agent.
	// +required
	Spec AgentSpec `json:"spec,omitzero"`

	// status defines the observed state of Agent.
	// +optional
	Status AgentStatus `json:"status,omitzero"`
}

Agent defines a cluster-scoped agent tier (e.g., "default", "smart", "fast"). The cluster admin creates Agent resources to configure LLM infrastructure and runtime settings. Proposals reference agents by name per step.

Agent is cluster-scoped. The metadata.name serves as the tier identifier. The "default" agent must exist; "smart" and "fast" are optional (the operator auto-links to "default" if absent).

Example — a high-capability agent tier:

apiVersion: agentic.openshift.io/v1alpha1
kind: Agent
metadata:
  name: smart
spec:
  llmProvider:
    name: vertex-ai
  model: claude-opus-4-6
  timeouts:
    analysisSeconds: 300
    executionSeconds: 600
  maxTurns: 200

Example — a fast, cost-efficient agent tier:

apiVersion: agentic.openshift.io/v1alpha1
kind: Agent
metadata:
  name: fast
spec:
  llmProvider:
    name: vertex-ai
  model: claude-haiku-4-5
  timeouts:
    analysisSeconds: 120
    executionSeconds: 300
  maxTurns: 100

func (*Agent) DeepCopy

func (in *Agent) DeepCopy() *Agent

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Agent.

func (*Agent) DeepCopyInto

func (in *Agent) DeepCopyInto(out *Agent)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*Agent) DeepCopyObject

func (in *Agent) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type AgentList

type AgentList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []Agent `json:"items"`
}

AgentList contains a list of Agent.

func (*AgentList) DeepCopy

func (in *AgentList) DeepCopy() *AgentList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentList.

func (*AgentList) DeepCopyInto

func (in *AgentList) DeepCopyInto(out *AgentList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*AgentList) DeepCopyObject

func (in *AgentList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type AgentSpec

type AgentSpec struct {
	// llmProvider references a cluster-scoped LLMProvider CR that supplies the
	// LLM backend for this agent tier.
	// +required
	LLMProvider LLMProviderReference `json:"llmProvider,omitzero"`

	// model is the LLM model identifier as recognized by the provider
	// (e.g., "claude-opus-4-6", "claude-haiku-4-5", "gpt-4o").
	// Must start with an alphanumeric character and may contain
	// alphanumerics, dots, hyphens, underscores, slashes, colons,
	// and at-signs. Maximum 256 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=256
	// +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9][a-zA-Z0-9._\\\\-/:@]*$')",message="model must start with an alphanumeric character and contain only alphanumerics, dots, hyphens, underscores, slashes, colons, and at-signs"
	Model string `json:"model,omitempty"`

	// timeouts configures per-step and per-turn timeout limits.
	// When omitted, the agent sandbox uses its built-in defaults.
	// +optional
	Timeouts AgentTimeouts `json:"timeouts,omitzero"`

	// maxTurns is the maximum number of tool-use turns the agent may take
	// in a single step invocation. Prevents runaway loops.
	// When omitted, the agent sandbox uses its built-in default.
	// Minimum 1, maximum 500.
	// +optional
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=500
	MaxTurns int32 `json:"maxTurns,omitempty"`
}

AgentSpec defines the desired state of Agent.

func (*AgentSpec) DeepCopy

func (in *AgentSpec) DeepCopy() *AgentSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentSpec.

func (*AgentSpec) DeepCopyInto

func (in *AgentSpec) DeepCopyInto(out *AgentSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type AgentStatus

type AgentStatus struct {
	// conditions represent the latest available observations of the
	// Agent's state. The Ready condition summarizes whether all
	// referenced resources (LLMProvider, Secrets) are present.
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	// +optional
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=8
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
}

AgentStatus defines the observed state of Agent. The operator validates that all referenced resources exist and reports readiness via standard Kubernetes conditions. An empty status (`status: {}`) is the initial state before the operator's first reconcile.

+kubebuilder:validation:MinProperties=1

func (*AgentStatus) DeepCopy

func (in *AgentStatus) DeepCopy() *AgentStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentStatus.

func (*AgentStatus) DeepCopyInto

func (in *AgentStatus) DeepCopyInto(out *AgentStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type AgentTimeouts

type AgentTimeouts struct {
	// analysisSeconds is the timeout for the analysis step in seconds.
	// +optional
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=3600
	AnalysisSeconds int32 `json:"analysisSeconds,omitempty"`

	// executionSeconds is the timeout for the execution step in seconds.
	// +optional
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=3600
	ExecutionSeconds int32 `json:"executionSeconds,omitempty"`

	// verificationSeconds is the timeout for the verification step in seconds.
	// +optional
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=3600
	VerificationSeconds int32 `json:"verificationSeconds,omitempty"`

	// chatSeconds is the timeout for each chat turn with the LLM in seconds.
	// +optional
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=600
	ChatSeconds int32 `json:"chatSeconds,omitempty"`
}

AgentTimeouts configures per-step and per-turn timeout limits. All values are in seconds.

+kubebuilder:validation:MinProperties=1

func (*AgentTimeouts) DeepCopy

func (in *AgentTimeouts) DeepCopy() *AgentTimeouts

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentTimeouts.

func (*AgentTimeouts) DeepCopyInto

func (in *AgentTimeouts) DeepCopyInto(out *AgentTimeouts)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type AnalysisApproval

type AnalysisApproval struct {
	// agent is the Agent CR for this step. Defaults to "default".
	// +optional
	// +default="default"
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	// +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="must be a valid DNS subdomain: lowercase alphanumeric characters, hyphens, and dots"
	Agent string `json:"agent,omitempty"`
}

AnalysisApproval contains approval parameters for the analysis step.

+kubebuilder:validation:MinProperties=1

func (*AnalysisApproval) DeepCopy

func (in *AnalysisApproval) DeepCopy() *AnalysisApproval

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalysisApproval.

func (*AnalysisApproval) DeepCopyInto

func (in *AnalysisApproval) DeepCopyInto(out *AnalysisApproval)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type AnalysisOutput

type AnalysisOutput struct {
	// mode controls which built-in properties the analysis output schema
	// includes. Default includes all built-in properties (diagnosis,
	// proposal, summary, rbac, verification). Minimal includes only the
	// base structure (options array with title per option). Omit or set
	// to "Default" for standard remediation workflows.
	// +optional
	// +default="Default"
	Mode AnalysisOutputMode `json:"mode,omitempty"`

	// schema is a JSON Schema injected as a required "components"
	// property in each analysis output option. Use this to require
	// adapter-specific structured data beyond the base analysis schema.
	// +optional
	// +kubebuilder:validation:Schemaless
	// +kubebuilder:validation:Type=object
	// +kubebuilder:pruning:PreserveUnknownFields
	Schema *apiextensionsv1.JSONSchemaProps `json:"schema,omitempty"`
}

AnalysisOutput configures the analysis step's structured output schema. The mode field controls which built-in properties are included. The schema field optionally defines adapter-specific structured data that is injected as a required "components" property in each option.

+kubebuilder:validation:MinProperties=1 +kubebuilder:validation:XValidation:rule="self.mode != 'Minimal' || has(self.schema)",message="schema is required when mode is Minimal"

func (*AnalysisOutput) DeepCopy

func (in *AnalysisOutput) DeepCopy() *AnalysisOutput

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalysisOutput.

func (*AnalysisOutput) DeepCopyInto

func (in *AnalysisOutput) DeepCopyInto(out *AnalysisOutput)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (AnalysisOutput) IsZero

func (a AnalysisOutput) IsZero() bool

type AnalysisOutputMode

type AnalysisOutputMode string

AnalysisOutputMode controls which built-in properties the analysis output schema includes. Use Default to get the full schema (diagnosis, proposal, RBAC, verification). Use Minimal to get only the base structure (options array with title) — suitable for analysis-only proposals that define their own output shape via the schema field.

Allowed values:

  • "Default" — Full analysis output schema with all built-in properties.
  • "Minimal" — Base structure only (options array with title per option).

+kubebuilder:validation:Enum=Default;Minimal

const (
	// AnalysisOutputModeDefault uses the full analysis output schema with
	// all built-in properties (diagnosis, proposal, summary, rbac, verification).
	AnalysisOutputModeDefault AnalysisOutputMode = "Default"
	// AnalysisOutputModeMinimal uses a minimal analysis output schema with
	// only the base structure (options array with title per option).
	// Built-in properties are omitted unless required by the workflow
	// (e.g., rbac is added when an execution step exists).
	AnalysisOutputModeMinimal AnalysisOutputMode = "Minimal"
)

type AnalysisResult

type AnalysisResult struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is the standard object metadata.
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty"`

	// spec contains the immutable identity fields for this result.
	// +required
	// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec is immutable"
	Spec AnalysisResultSpec `json:"spec,omitzero"`

	// status contains result data and conditions.
	// +optional
	Status AnalysisResultStatus `json:"status,omitzero"`
}

AnalysisResult records the output of a single analysis step execution. Created by the operator after the analysis agent completes. Owned by the parent Proposal for garbage collection.

func (*AnalysisResult) DeepCopy

func (in *AnalysisResult) DeepCopy() *AnalysisResult

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalysisResult.

func (*AnalysisResult) DeepCopyInto

func (in *AnalysisResult) DeepCopyInto(out *AnalysisResult)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*AnalysisResult) DeepCopyObject

func (in *AnalysisResult) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*AnalysisResult) GetConditions

func (r *AnalysisResult) GetConditions() []metav1.Condition

func (*AnalysisResult) SetConditions

func (r *AnalysisResult) SetConditions(c []metav1.Condition)

type AnalysisResultList

type AnalysisResultList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []AnalysisResult `json:"items"`
}

AnalysisResultList contains a list of AnalysisResult.

func (*AnalysisResultList) DeepCopy

func (in *AnalysisResultList) DeepCopy() *AnalysisResultList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalysisResultList.

func (*AnalysisResultList) DeepCopyInto

func (in *AnalysisResultList) DeepCopyInto(out *AnalysisResultList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*AnalysisResultList) DeepCopyObject

func (in *AnalysisResultList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type AnalysisResultSpec

type AnalysisResultSpec struct {
	// proposalName is the name of the parent Proposal in the same namespace.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	ProposalName string `json:"proposalName,omitempty"`
}

AnalysisResultSpec contains the immutable identity fields for an AnalysisResult.

func (*AnalysisResultSpec) DeepCopy

func (in *AnalysisResultSpec) DeepCopy() *AnalysisResultSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalysisResultSpec.

func (*AnalysisResultSpec) DeepCopyInto

func (in *AnalysisResultSpec) DeepCopyInto(out *AnalysisResultSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type AnalysisResultStatus

type AnalysisResultStatus struct {
	// conditions track the lifecycle of this result.
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	// +optional
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=8
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`

	// options contains the remediation options returned by the analysis agent.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=10
	Options []RemediationOption `json:"options,omitempty"`

	// sandbox tracks the sandbox pod used for this analysis.
	// +optional
	Sandbox SandboxInfo `json:"sandbox,omitzero"`

	// failureReason is populated when the step failed due to a system error.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=8192
	FailureReason string `json:"failureReason,omitempty"`
}

AnalysisResultStatus is the status of an AnalysisResult.

+kubebuilder:validation:MinProperties=1

func (*AnalysisResultStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalysisResultStatus.

func (*AnalysisResultStatus) DeepCopyInto

func (in *AnalysisResultStatus) DeepCopyInto(out *AnalysisResultStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type AnalysisStepStatus

type AnalysisStepStatus struct {
	// conditions for this step.
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	// +optional
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=8
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
	// sandbox tracks the sandbox used.
	// +optional
	Sandbox SandboxInfo `json:"sandbox,omitzero"`
	// results references AnalysisResult CRs, newest last.
	// Each entry corresponds to one analysis attempt.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=20
	Results []StepResultRef `json:"results,omitempty"`
}

AnalysisStepStatus is the observed state of the analysis step.

+kubebuilder:validation:MinProperties=1

func (*AnalysisStepStatus) DeepCopy

func (in *AnalysisStepStatus) DeepCopy() *AnalysisStepStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalysisStepStatus.

func (*AnalysisStepStatus) DeepCopyInto

func (in *AnalysisStepStatus) DeepCopyInto(out *AnalysisStepStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type AnthropicConfig

type AnthropicConfig struct {
	// credentialsSecret references a Secret in the operator namespace
	// (openshift-lightspeed) containing the Anthropic API credentials.
	// The Secret must contain the key ANTHROPIC_API_KEY.
	// +required
	CredentialsSecret SecretReference `json:"credentialsSecret,omitzero"`

	// url is an optional override for the Anthropic API endpoint.
	// Only needed for custom deployments or API proxies.
	// Must be a valid HTTP or HTTPS URL with a hostname. Paths and query
	// parameters are allowed. Fragments and userinfo are not permitted.
	// Maximum 2048 characters.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=2048
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getScheme() in ['http', 'https']",message="must use http or https scheme"
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getHostname() != ”",message="must include a hostname"
	// +kubebuilder:validation:XValidation:rule="!self.contains('@')",message="userinfo is not allowed in URL"
	// +kubebuilder:validation:XValidation:rule="!self.contains('#')",message="fragments are not allowed in URL"
	URL string `json:"url,omitempty"`
}

AnthropicConfig contains configuration for the Anthropic API provider.

func (*AnthropicConfig) DeepCopy

func (in *AnthropicConfig) DeepCopy() *AnthropicConfig

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnthropicConfig.

func (*AnthropicConfig) DeepCopyInto

func (in *AnthropicConfig) DeepCopyInto(out *AnthropicConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ApprovalDecision

type ApprovalDecision string

ApprovalDecision indicates whether a stage is approved or denied. +kubebuilder:validation:Enum=Approved;Denied

const (
	ApprovalDecisionApproved ApprovalDecision = "Approved"
	ApprovalDecisionDenied   ApprovalDecision = "Denied"
)

type ApprovalMode

type ApprovalMode string

ApprovalMode controls whether a step requires explicit user approval. +kubebuilder:validation:Enum=Automatic;Manual

const (
	ApprovalModeAutomatic ApprovalMode = "Automatic"
	ApprovalModeManual    ApprovalMode = "Manual"
)

type ApprovalPolicy

type ApprovalPolicy struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is the standard object metadata.
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty"`

	// spec defines the desired approval policy.
	// +required
	Spec ApprovalPolicySpec `json:"spec,omitzero"`
}

ApprovalPolicy is a cluster-scoped singleton that configures default approval behavior for proposal workflow steps. The cluster admin creates a single ApprovalPolicy named "cluster" to control which steps auto-approve.

Steps not listed in the policy default to Manual (require explicit user approval on the ProposalApproval resource).

Example:

apiVersion: agentic.openshift.io/v1alpha1
kind: ApprovalPolicy
metadata:
  name: cluster
spec:
  stages:
    - name: Analysis
      approval: Automatic
    - name: Execution
      approval: Manual
    - name: Verification
      approval: Automatic

func (*ApprovalPolicy) DeepCopy

func (in *ApprovalPolicy) DeepCopy() *ApprovalPolicy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApprovalPolicy.

func (*ApprovalPolicy) DeepCopyInto

func (in *ApprovalPolicy) DeepCopyInto(out *ApprovalPolicy)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ApprovalPolicy) DeepCopyObject

func (in *ApprovalPolicy) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type ApprovalPolicyList

type ApprovalPolicyList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []ApprovalPolicy `json:"items"`
}

ApprovalPolicyList contains a list of ApprovalPolicy.

func (*ApprovalPolicyList) DeepCopy

func (in *ApprovalPolicyList) DeepCopy() *ApprovalPolicyList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApprovalPolicyList.

func (*ApprovalPolicyList) DeepCopyInto

func (in *ApprovalPolicyList) DeepCopyInto(out *ApprovalPolicyList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ApprovalPolicyList) DeepCopyObject

func (in *ApprovalPolicyList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type ApprovalPolicySpec

type ApprovalPolicySpec struct {
	// stages configures the approval mode for each workflow step.
	// Omitted steps default to Manual.
	// +optional
	// +listType=map
	// +listMapKey=name
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=4
	Stages []ApprovalPolicyStage `json:"stages,omitempty"`

	// maxAttempts sets the maximum number of execution retry attempts
	// allowed for proposals. When verification fails, the operator retries
	// execution up to this limit before escalating. Defaults to 1 if omitted.
	// +optional
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=3
	MaxAttempts int32 `json:"maxAttempts,omitempty"`

	// maxConcurrentProposals sets the maximum number of proposals the
	// operator reconciles concurrently. Higher values allow more proposals
	// to run in parallel but consume more cluster resources.
	// Defaults to 5 if omitted.
	// +optional
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=20
	// +default=5
	MaxConcurrentProposals int32 `json:"maxConcurrentProposals,omitempty"`
}

ApprovalPolicySpec defines the desired state of ApprovalPolicy.

+kubebuilder:validation:MinProperties=1

func (*ApprovalPolicySpec) DeepCopy

func (in *ApprovalPolicySpec) DeepCopy() *ApprovalPolicySpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApprovalPolicySpec.

func (*ApprovalPolicySpec) DeepCopyInto

func (in *ApprovalPolicySpec) DeepCopyInto(out *ApprovalPolicySpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ApprovalPolicyStage

type ApprovalPolicyStage struct {
	// name is the workflow step this policy applies to.
	// Allowed values: Analysis, Execution, Verification, Escalation.
	// +required
	Name SandboxStep `json:"name,omitempty"`

	// approval controls whether this step auto-approves or requires
	// explicit user approval on the ProposalApproval resource.
	// Allowed values: Automatic (step runs without user approval),
	// Manual (step waits for explicit approval on ProposalApproval).
	// +required
	Approval ApprovalMode `json:"approval,omitempty"`
}

ApprovalPolicyStage configures the approval mode for a single workflow step.

func (*ApprovalPolicyStage) DeepCopy

func (in *ApprovalPolicyStage) DeepCopy() *ApprovalPolicyStage

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApprovalPolicyStage.

func (*ApprovalPolicyStage) DeepCopyInto

func (in *ApprovalPolicyStage) DeepCopyInto(out *ApprovalPolicyStage)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ApprovalStage

type ApprovalStage struct {
	// type identifies which workflow step this approval is for.
	// +required
	Type ApprovalStageType `json:"type,omitempty"`

	// decision indicates whether this stage is approved or denied.
	// Denying any stage terminates the entire proposal, even if
	// earlier stages were already approved. Once set to Denied,
	// it cannot be changed.
	// +optional
	Decision ApprovalDecision `json:"decision,omitempty"`

	// analysis contains approval parameters for the analysis step.
	// Required when type is Analysis.
	// +optional
	Analysis AnalysisApproval `json:"analysis,omitzero"`

	// execution contains approval parameters for the execution step.
	// Required when type is Execution.
	// +optional
	Execution ExecutionApproval `json:"execution,omitzero"`

	// verification contains approval parameters for the verification step.
	// Required when type is Verification.
	// +optional
	Verification VerificationApproval `json:"verification,omitzero"`

	// escalation contains approval parameters for the escalation step.
	// Required when type is Escalation.
	// +optional
	Escalation EscalationApproval `json:"escalation,omitzero"`
}

ApprovalStage is a discriminated union representing approval for one workflow step. Presence in spec.stages indicates approval; absence means not yet approved (controller checks ApprovalPolicy for auto-approve).

+kubebuilder:validation:XValidation:rule="self.type == 'Analysis' ? has(self.analysis) : !has(self.analysis)",message="analysis is required when type is Analysis, and forbidden otherwise" +kubebuilder:validation:XValidation:rule="self.type == 'Execution' ? has(self.execution) : !has(self.execution)",message="execution is required when type is Execution, and forbidden otherwise" +kubebuilder:validation:XValidation:rule="self.type == 'Verification' ? has(self.verification) : !has(self.verification)",message="verification is required when type is Verification, and forbidden otherwise" +kubebuilder:validation:XValidation:rule="self.type == 'Escalation' ? has(self.escalation) : !has(self.escalation)",message="escalation is required when type is Escalation, and forbidden otherwise"

func (*ApprovalStage) DeepCopy

func (in *ApprovalStage) DeepCopy() *ApprovalStage

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApprovalStage.

func (*ApprovalStage) DeepCopyInto

func (in *ApprovalStage) DeepCopyInto(out *ApprovalStage)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ApprovalStageStatus

type ApprovalStageStatus struct {
	// conditions for this approval stage.
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	// +optional
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=8
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`

	// name identifies the workflow step.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	Name string `json:"name,omitempty"`
}

ApprovalStageStatus is the observed state of a single approval stage.

func (*ApprovalStageStatus) DeepCopy

func (in *ApprovalStageStatus) DeepCopy() *ApprovalStageStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApprovalStageStatus.

func (*ApprovalStageStatus) DeepCopyInto

func (in *ApprovalStageStatus) DeepCopyInto(out *ApprovalStageStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ApprovalStageType

type ApprovalStageType string

ApprovalStageType identifies which workflow step an approval entry applies to. +kubebuilder:validation:Enum=Analysis;Execution;Verification;Escalation

const (
	ApprovalStageAnalysis     ApprovalStageType = "Analysis"
	ApprovalStageExecution    ApprovalStageType = "Execution"
	ApprovalStageVerification ApprovalStageType = "Verification"
	ApprovalStageEscalation   ApprovalStageType = "Escalation"
)

type AzureOpenAIConfig

type AzureOpenAIConfig struct {
	// credentialsSecret references a Secret in the operator namespace
	// (openshift-lightspeed) containing the Azure OpenAI API credentials.
	// The Secret must contain the key AZURE_OPENAI_API_KEY.
	// +required
	CredentialsSecret SecretReference `json:"credentialsSecret,omitzero"`

	// endpoint is the Azure OpenAI resource endpoint
	// (e.g., "https://my-resource.openai.azure.com").
	// Must be a valid HTTP or HTTPS URL with a hostname. Paths and query
	// parameters are allowed. Fragments and userinfo are not permitted.
	// Maximum 2048 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=2048
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getScheme() in ['http', 'https']",message="must use http or https scheme"
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getHostname() != ”",message="must include a hostname"
	// +kubebuilder:validation:XValidation:rule="!self.contains('@')",message="userinfo is not allowed in URL"
	// +kubebuilder:validation:XValidation:rule="!self.contains('#')",message="fragments are not allowed in URL"
	Endpoint string `json:"endpoint,omitempty"`

	// apiVersion is the Azure OpenAI API version. Azure API versions use
	// a date-based format: YYYY-MM-DD with an optional "-preview" suffix
	// (e.g., "2024-02-01", "2024-08-01-preview").
	// When omitted, the SDK default is used.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=32
	// +kubebuilder:validation:XValidation:rule="self.matches('^[0-9]{4}-[0-9]{2}-[0-9]{2}(-preview)?$')",message="apiVersion must be a date in YYYY-MM-DD format with an optional -preview suffix"
	APIVersion string `json:"apiVersion,omitempty"`

	// url is an optional override for the Azure OpenAI API endpoint.
	// Only needed for custom deployments or API proxies. This is separate
	// from the required 'endpoint' field which identifies the Azure resource.
	// Must be a valid HTTP or HTTPS URL with a hostname. Paths and query
	// parameters are allowed. Fragments and userinfo are not permitted.
	// Maximum 2048 characters.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=2048
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getScheme() in ['http', 'https']",message="must use http or https scheme"
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getHostname() != ”",message="must include a hostname"
	// +kubebuilder:validation:XValidation:rule="!self.contains('@')",message="userinfo is not allowed in URL"
	// +kubebuilder:validation:XValidation:rule="!self.contains('#')",message="fragments are not allowed in URL"
	URL string `json:"url,omitempty"`
}

AzureOpenAIConfig contains configuration for the Azure OpenAI Service provider.

func (*AzureOpenAIConfig) DeepCopy

func (in *AzureOpenAIConfig) DeepCopy() *AzureOpenAIConfig

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureOpenAIConfig.

func (*AzureOpenAIConfig) DeepCopyInto

func (in *AzureOpenAIConfig) DeepCopyInto(out *AzureOpenAIConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type CheckResult

type CheckResult string

CheckResult indicates whether a verification check passed. +kubebuilder:validation:Enum=Passed;Failed

const (
	CheckResultPassed CheckResult = "Passed"
	CheckResultFailed CheckResult = "Failed"
)

type ConditionOutcome

type ConditionOutcome string

ConditionOutcome indicates whether the target condition improved after remediation. +kubebuilder:validation:Enum=Improved;Unchanged;Degraded

const (
	ConditionOutcomeImproved  ConditionOutcome = "Improved"
	ConditionOutcomeUnchanged ConditionOutcome = "Unchanged"
	ConditionOutcomeDegraded  ConditionOutcome = "Degraded"
)

type ConfidenceLevel

type ConfidenceLevel string

ConfidenceLevel is the agent's self-assessed confidence in its diagnosis. Higher confidence generally correlates with clearer symptoms and more deterministic root causes.

  • "Low" — Uncertain diagnosis; symptoms are ambiguous or incomplete.
  • "Medium" — Reasonable diagnosis; symptoms point to a likely cause.
  • "High" — Strong diagnosis; clear symptoms with deterministic root cause.

+kubebuilder:validation:Enum=Low;Medium;High

const (
	ConfidenceLevelLow    ConfidenceLevel = "Low"
	ConfidenceLevelMedium ConfidenceLevel = "Medium"
	ConfidenceLevelHigh   ConfidenceLevel = "High"
)

type DiagnosisResult

type DiagnosisResult struct {
	// summary is a Markdown-formatted diagnosis summary explaining the
	// problem, its symptoms, and the agent's findings. Maximum 8192 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=8192
	Summary string `json:"summary,omitempty"`
	// confidence is the agent's self-assessed confidence in its diagnosis.
	// Higher confidence generally correlates with clearer symptoms and
	// more deterministic root causes.
	// +required
	Confidence ConfidenceLevel `json:"confidence,omitempty"`
	// rootCause is a concise Markdown-formatted description of the identified
	// root cause (e.g., "OOMKilled due to memory limit of 256Mi").
	// Maximum 1024 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=1024
	RootCause string `json:"rootCause,omitempty"`
}

DiagnosisResult contains the root cause analysis from the analysis agent. This is populated by the agent during the analysis step and stored in the AnalysisStepStatus as part of a RemediationOption. Users see this in the console UI when reviewing the proposal.

func (*DiagnosisResult) DeepCopy

func (in *DiagnosisResult) DeepCopy() *DiagnosisResult

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DiagnosisResult.

func (*DiagnosisResult) DeepCopyInto

func (in *DiagnosisResult) DeepCopyInto(out *DiagnosisResult)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type EscalationApproval

type EscalationApproval struct {
	// agent is the Agent CR for this step. Defaults to "default".
	// +optional
	// +default="default"
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	// +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="must be a valid DNS subdomain: lowercase alphanumeric characters, hyphens, and dots"
	Agent string `json:"agent,omitempty"`
}

EscalationApproval contains approval parameters for the escalation step.

+kubebuilder:validation:MinProperties=1

func (*EscalationApproval) DeepCopy

func (in *EscalationApproval) DeepCopy() *EscalationApproval

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EscalationApproval.

func (*EscalationApproval) DeepCopyInto

func (in *EscalationApproval) DeepCopyInto(out *EscalationApproval)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type EscalationResult

type EscalationResult struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is the standard object metadata.
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty"`

	// spec contains the immutable identity fields for this result.
	// +required
	// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec is immutable"
	Spec EscalationResultSpec `json:"spec,omitzero"`

	// status contains result data and conditions.
	// +optional
	Status EscalationResultStatus `json:"status,omitzero"`
}

EscalationResult records the output of the escalation step. Created by the operator after the escalation agent completes. Owned by the parent Proposal for garbage collection.

func (*EscalationResult) DeepCopy

func (in *EscalationResult) DeepCopy() *EscalationResult

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EscalationResult.

func (*EscalationResult) DeepCopyInto

func (in *EscalationResult) DeepCopyInto(out *EscalationResult)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*EscalationResult) DeepCopyObject

func (in *EscalationResult) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*EscalationResult) GetConditions

func (r *EscalationResult) GetConditions() []metav1.Condition

func (*EscalationResult) SetConditions

func (r *EscalationResult) SetConditions(c []metav1.Condition)

type EscalationResultList

type EscalationResultList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []EscalationResult `json:"items"`
}

EscalationResultList contains a list of EscalationResult.

func (*EscalationResultList) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EscalationResultList.

func (*EscalationResultList) DeepCopyInto

func (in *EscalationResultList) DeepCopyInto(out *EscalationResultList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*EscalationResultList) DeepCopyObject

func (in *EscalationResultList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type EscalationResultSpec

type EscalationResultSpec struct {
	// proposalName is the name of the parent Proposal in the same namespace.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	ProposalName string `json:"proposalName,omitempty"`
}

EscalationResultSpec contains the immutable identity fields for an EscalationResult.

func (*EscalationResultSpec) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EscalationResultSpec.

func (*EscalationResultSpec) DeepCopyInto

func (in *EscalationResultSpec) DeepCopyInto(out *EscalationResultSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type EscalationResultStatus

type EscalationResultStatus struct {
	// conditions track the lifecycle of this result.
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	// +optional
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=8
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`

	// summary is a Markdown-formatted escalation summary.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=32768
	Summary string `json:"summary,omitempty"`

	// content is freeform escalation content produced by the agent.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=65536
	Content string `json:"content,omitempty"`

	// sandbox tracks the sandbox pod used for this escalation.
	// +optional
	Sandbox SandboxInfo `json:"sandbox,omitzero"`

	// failureReason is populated when the step failed due to a system error.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=8192
	FailureReason string `json:"failureReason,omitempty"`
}

EscalationResultStatus is the status of an EscalationResult.

+kubebuilder:validation:MinProperties=1

func (*EscalationResultStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EscalationResultStatus.

func (*EscalationResultStatus) DeepCopyInto

func (in *EscalationResultStatus) DeepCopyInto(out *EscalationResultStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type EscalationStepStatus

type EscalationStepStatus struct {
	// conditions for this step.
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	// +optional
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=8
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
	// sandbox tracks the sandbox used.
	// +optional
	Sandbox SandboxInfo `json:"sandbox,omitzero"`
	// results references EscalationResult CRs, newest last.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=20
	Results []StepResultRef `json:"results,omitempty"`
}

EscalationStepStatus is the observed state of the escalation step. The operator injects this step when retries are exhausted; it is not declared in the Proposal spec.

+kubebuilder:validation:MinProperties=1

func (*EscalationStepStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EscalationStepStatus.

func (*EscalationStepStatus) DeepCopyInto

func (in *EscalationStepStatus) DeepCopyInto(out *EscalationStepStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ExecutionAction

type ExecutionAction struct {
	// type is the action category (e.g., "patch", "scale", "restart").
	// Maximum 256 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=256
	Type string `json:"type,omitempty"`
	// description is a Markdown-formatted explanation of what the agent did
	// (e.g., "Patched deployment/web to set memory limit to 512Mi").
	// Maximum 4096 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=4096
	Description string `json:"description,omitempty"`
	// outcome indicates whether this individual action succeeded.
	// Must be one of: Succeeded, Failed.
	// +required
	Outcome ActionOutcome `json:"outcome,omitempty"`
	// output is the command output or API response from the action.
	// Maximum 32768 characters.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=32768
	Output string `json:"output,omitempty"`
	// error is the error message if the action failed.
	// Maximum 8192 characters.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=8192
	Error string `json:"error,omitempty"`
}

ExecutionAction describes a single action taken by the execution agent during the execution step. These are recorded in ExecutionStepStatus to provide an audit trail of what the agent actually did.

func (*ExecutionAction) DeepCopy

func (in *ExecutionAction) DeepCopy() *ExecutionAction

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecutionAction.

func (*ExecutionAction) DeepCopyInto

func (in *ExecutionAction) DeepCopyInto(out *ExecutionAction)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ExecutionApproval

type ExecutionApproval struct {
	// agent is the Agent CR for this step. Defaults to "default".
	// +optional
	// +default="default"
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	// +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="must be a valid DNS subdomain: lowercase alphanumeric characters, hyphens, and dots"
	Agent string `json:"agent,omitempty"`

	// option is the 0-based index into the analysis options array
	// selecting which remediation approach to execute.
	// +optional
	// +kubebuilder:validation:Minimum=0
	Option *int32 `json:"option,omitempty"`

	// maxAttempts is the number of execution retry attempts approved
	// for this proposal. Must not exceed ApprovalPolicy.spec.maxAttempts.
	// Defaults to 1 if unset.
	// +optional
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=3
	MaxAttempts int32 `json:"maxAttempts,omitempty"`
}

ExecutionApproval contains approval parameters for the execution step.

+kubebuilder:validation:MinProperties=1

func (*ExecutionApproval) DeepCopy

func (in *ExecutionApproval) DeepCopy() *ExecutionApproval

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecutionApproval.

func (*ExecutionApproval) DeepCopyInto

func (in *ExecutionApproval) DeepCopyInto(out *ExecutionApproval)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ExecutionResult

type ExecutionResult struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is the standard object metadata.
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty"`

	// spec contains the immutable identity fields for this result.
	// +required
	// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec is immutable"
	Spec ExecutionResultSpec `json:"spec,omitzero"`

	// status contains result data and conditions.
	// +optional
	Status ExecutionResultStatus `json:"status,omitzero"`
}

ExecutionResult records the output of a single execution step execution. Created by the operator after the execution agent completes. Owned by the parent Proposal for garbage collection.

func (*ExecutionResult) DeepCopy

func (in *ExecutionResult) DeepCopy() *ExecutionResult

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecutionResult.

func (*ExecutionResult) DeepCopyInto

func (in *ExecutionResult) DeepCopyInto(out *ExecutionResult)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ExecutionResult) DeepCopyObject

func (in *ExecutionResult) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*ExecutionResult) GetConditions

func (r *ExecutionResult) GetConditions() []metav1.Condition

func (*ExecutionResult) SetConditions

func (r *ExecutionResult) SetConditions(c []metav1.Condition)

type ExecutionResultList

type ExecutionResultList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []ExecutionResult `json:"items"`
}

ExecutionResultList contains a list of ExecutionResult.

func (*ExecutionResultList) DeepCopy

func (in *ExecutionResultList) DeepCopy() *ExecutionResultList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecutionResultList.

func (*ExecutionResultList) DeepCopyInto

func (in *ExecutionResultList) DeepCopyInto(out *ExecutionResultList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ExecutionResultList) DeepCopyObject

func (in *ExecutionResultList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type ExecutionResultSpec

type ExecutionResultSpec struct {
	// proposalName is the name of the parent Proposal in the same namespace.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	ProposalName string `json:"proposalName,omitempty"`

	// retryIndex is the 0-based retry index within the current analysis.
	// First execution has retryIndex 0, first retry has retryIndex 1, etc.
	// +required
	// +kubebuilder:validation:Minimum=0
	// +kubebuilder:validation:Maximum=2
	RetryIndex *int32 `json:"retryIndex,omitempty"`
}

ExecutionResultSpec contains the immutable identity fields for an ExecutionResult.

func (*ExecutionResultSpec) DeepCopy

func (in *ExecutionResultSpec) DeepCopy() *ExecutionResultSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecutionResultSpec.

func (*ExecutionResultSpec) DeepCopyInto

func (in *ExecutionResultSpec) DeepCopyInto(out *ExecutionResultSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ExecutionResultStatus

type ExecutionResultStatus struct {
	// conditions track the lifecycle of this result.
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	// +optional
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=8
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`

	// actionsTaken lists what the agent did.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=100
	ActionsTaken []ExecutionAction `json:"actionsTaken,omitempty"`

	// verification is the lightweight inline verification the execution
	// agent performs immediately after completing its actions.
	// +optional
	Verification ExecutionVerification `json:"verification,omitzero"`

	// sandbox tracks the sandbox pod used for this execution.
	// +optional
	Sandbox SandboxInfo `json:"sandbox,omitzero"`

	// failureReason is populated when the step failed due to a system error.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=8192
	FailureReason string `json:"failureReason,omitempty"`
}

ExecutionResultStatus is the status of an ExecutionResult.

+kubebuilder:validation:MinProperties=1

func (*ExecutionResultStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecutionResultStatus.

func (*ExecutionResultStatus) DeepCopyInto

func (in *ExecutionResultStatus) DeepCopyInto(out *ExecutionResultStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ExecutionStepStatus

type ExecutionStepStatus struct {
	// conditions for this step.
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	// +optional
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=8
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
	// sandbox tracks the sandbox used.
	// +optional
	Sandbox SandboxInfo `json:"sandbox,omitzero"`
	// retryCount tracks how many times execution+verification has been
	// retried for the current analysis option. Reset when a new analysis
	// is run (initial or revision). The operator increments this on each
	// objective verification failure before retrying execution.
	// +optional
	// +kubebuilder:validation:Minimum=0
	RetryCount *int32 `json:"retryCount,omitempty"`
	// results references ExecutionResult CRs, newest last.
	// Each entry corresponds to one execution attempt (including retries).
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=20
	Results []StepResultRef `json:"results,omitempty"`
}

ExecutionStepStatus is the observed state of the execution step.

+kubebuilder:validation:MinProperties=1

func (*ExecutionStepStatus) DeepCopy

func (in *ExecutionStepStatus) DeepCopy() *ExecutionStepStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecutionStepStatus.

func (*ExecutionStepStatus) DeepCopyInto

func (in *ExecutionStepStatus) DeepCopyInto(out *ExecutionStepStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ExecutionVerification

type ExecutionVerification struct {
	// conditionOutcome indicates whether the target condition improved
	// after the remediation (e.g., pod is no longer CrashLoopBackOff).
	// Must be one of: Improved, Unchanged, Degraded.
	// +required
	ConditionOutcome ConditionOutcome `json:"conditionOutcome,omitempty"`
	// summary is a Markdown-formatted summary of the inline verification.
	// Maximum 4096 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=4096
	Summary string `json:"summary,omitempty"`
}

ExecutionVerification is a lightweight inline verification that the execution agent performs immediately after completing its actions, before the formal verification step. This gives early signal on whether the remediation worked. In trust-mode workflows (verification skipped), this is the only verification that occurs.

func (*ExecutionVerification) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecutionVerification.

func (*ExecutionVerification) DeepCopyInto

func (in *ExecutionVerification) DeepCopyInto(out *ExecutionVerification)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GoogleCloudVertexConfig

type GoogleCloudVertexConfig struct {
	// credentialsSecret references a Secret in the operator namespace
	// (openshift-lightspeed) containing a GCP service account JSON key.
	// The Secret must contain the key GOOGLE_APPLICATION_CREDENTIALS.
	// +required
	CredentialsSecret SecretReference `json:"credentialsSecret,omitzero"`

	// projectID is the Google Cloud Project ID where Vertex AI is enabled.
	// A Project ID is a globally unique identifier that must be 6 to 30
	// characters in length, can only contain lowercase letters, digits, and
	// hyphens, must start with a letter, and cannot end with a hyphen.
	// +required
	// +kubebuilder:validation:MinLength=6
	// +kubebuilder:validation:MaxLength=30
	// +kubebuilder:validation:XValidation:rule="self.matches('^[a-z][a-z0-9-]*[a-z0-9]$')",message="projectID must start with a lowercase letter, contain only lowercase letters, digits, and hyphens, and cannot end with a hyphen"
	ProjectID string `json:"projectID,omitempty"`

	// region is the GCP region for the Vertex AI endpoint.
	// Must begin with a lowercase letter and end with a lowercase
	// alphanumeric character. May contain lowercase letters, digits,
	// and hyphens (e.g., "us-central1", "europe-west4", "asia-southeast1").
	// +required
	// +kubebuilder:validation:MinLength=2
	// +kubebuilder:validation:MaxLength=63
	// +kubebuilder:validation:XValidation:rule="self.matches('^[a-z][a-z0-9-]*[a-z0-9]$')",message="region must contain only lowercase letters, digits, and hyphens, start with a letter, and not end with a hyphen"
	Region string `json:"region,omitempty"`

	// url is an optional override for the Vertex AI API endpoint.
	// Only needed for custom deployments or API proxies.
	// Must be a valid HTTP or HTTPS URL with a hostname. Paths and query
	// parameters are allowed. Fragments and userinfo are not permitted.
	// Maximum 2048 characters.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=2048
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getScheme() in ['http', 'https']",message="must use http or https scheme"
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getHostname() != ”",message="must include a hostname"
	// +kubebuilder:validation:XValidation:rule="!self.contains('@')",message="userinfo is not allowed in URL"
	// +kubebuilder:validation:XValidation:rule="!self.contains('#')",message="fragments are not allowed in URL"
	URL string `json:"url,omitempty"`
}

GoogleCloudVertexConfig contains configuration for the Google Cloud Vertex AI provider.

func (*GoogleCloudVertexConfig) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GoogleCloudVertexConfig.

func (*GoogleCloudVertexConfig) DeepCopyInto

func (in *GoogleCloudVertexConfig) DeepCopyInto(out *GoogleCloudVertexConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type LLMProvider

type LLMProvider struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is the standard object metadata.
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty"`

	// spec defines the desired state of LLMProvider.
	// +required
	Spec LLMProviderSpec `json:"spec,omitzero"`
}

LLMProvider defines an LLM provider configuration. It is the first link in the CRD chain (LLMProvider -> Agent -> Workflow -> Proposal) and is referenced by Agent resources via spec.llmProvider.

LLMProvider is cluster-scoped — the cluster admin manages LLM infrastructure centrally. The operator uses the credentials to configure the LLM client inside agent sandbox pods. The model is specified on the Agent CR, allowing multiple agents to share one LLMProvider with different models.

Typically you create one provider per backend (e.g., one for Vertex AI) and then reference it from multiple Agent resources with different models.

Example — a Vertex AI provider (model specified on Agent, not here):

apiVersion: agentic.openshift.io/v1alpha1
kind: LLMProvider
metadata:
  name: vertex-ai
spec:
  type: GoogleCloudVertex
  googleCloudVertex:
    credentialsSecret:
      name: llm-credentials
    projectID: my-gcp-project
    region: us-central1

func (*LLMProvider) DeepCopy

func (in *LLMProvider) DeepCopy() *LLMProvider

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LLMProvider.

func (*LLMProvider) DeepCopyInto

func (in *LLMProvider) DeepCopyInto(out *LLMProvider)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*LLMProvider) DeepCopyObject

func (in *LLMProvider) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type LLMProviderList

type LLMProviderList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []LLMProvider `json:"items"`
}

LLMProviderList contains a list of LLMProvider.

func (*LLMProviderList) DeepCopy

func (in *LLMProviderList) DeepCopy() *LLMProviderList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LLMProviderList.

func (*LLMProviderList) DeepCopyInto

func (in *LLMProviderList) DeepCopyInto(out *LLMProviderList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*LLMProviderList) DeepCopyObject

func (in *LLMProviderList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type LLMProviderReference

type LLMProviderReference struct {
	// name of the LLMProvider. Must be a valid RFC 1123 DNS subdomain.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	// +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="must be a valid DNS subdomain: lowercase alphanumeric characters, hyphens, and dots"
	Name string `json:"name,omitempty"`
}

LLMProviderReference references a cluster-scoped LLMProvider CR by name.

func (*LLMProviderReference) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LLMProviderReference.

func (*LLMProviderReference) DeepCopyInto

func (in *LLMProviderReference) DeepCopyInto(out *LLMProviderReference)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type LLMProviderSpec

type LLMProviderSpec struct {
	// type is a required field that configures which LLM provider backend
	// should be used.
	//
	// Allowed values are Anthropic, GoogleCloudVertex, OpenAI, AzureOpenAI,
	// and AWSBedrock.
	//
	// When set to Anthropic, agents referencing this provider will use the
	// Anthropic API directly, and the 'anthropic' field must be configured.
	//
	// When set to GoogleCloudVertex, agents referencing this provider will
	// use Google Cloud Vertex AI, and the 'googleCloudVertex' field must be
	// configured.
	//
	// When set to OpenAI, agents referencing this provider will use an
	// OpenAI-compatible API, and the 'openAI' field must be configured.
	//
	// When set to AzureOpenAI, agents referencing this provider will use
	// the Azure OpenAI Service, and the 'azureOpenAI' field must be
	// configured.
	//
	// When set to AWSBedrock, agents referencing this provider will use
	// AWS Bedrock, and the 'awsBedrock' field must be configured.
	// +required
	Type LLMProviderType `json:"type,omitempty"`

	// anthropic contains Anthropic-specific configuration.
	// Required when type is "Anthropic".
	// +optional
	Anthropic AnthropicConfig `json:"anthropic,omitzero"`

	// googleCloudVertex contains Google Cloud Vertex AI-specific configuration.
	// Required when type is "GoogleCloudVertex".
	// +optional
	GoogleCloudVertex GoogleCloudVertexConfig `json:"googleCloudVertex,omitzero"`

	// openAI contains OpenAI-specific configuration.
	// Required when type is "OpenAI".
	// +optional
	OpenAI OpenAIConfig `json:"openAI,omitzero"`

	// azureOpenAI contains Azure OpenAI Service-specific configuration.
	// Required when type is "AzureOpenAI".
	// +optional
	AzureOpenAI AzureOpenAIConfig `json:"azureOpenAI,omitzero"`

	// awsBedrock contains AWS Bedrock-specific configuration.
	// Required when type is "AWSBedrock".
	// +optional
	AWSBedrock AWSBedrockConfig `json:"awsBedrock,omitzero"`
}

LLMProviderSpec defines the desired state of LLMProvider.

The type field is the discriminator. Exactly one of the per-provider configuration fields (anthropic, googleCloudVertex, openAI, azureOpenAI, awsBedrock) must be set, matching the type value.

+kubebuilder:validation:XValidation:rule="self.type == 'Anthropic' ? has(self.anthropic) : !has(self.anthropic)",message="anthropic is required when type is Anthropic, and forbidden otherwise" +kubebuilder:validation:XValidation:rule="self.type == 'GoogleCloudVertex' ? has(self.googleCloudVertex) : !has(self.googleCloudVertex)",message="googleCloudVertex is required when type is GoogleCloudVertex, and forbidden otherwise" +kubebuilder:validation:XValidation:rule="self.type == 'OpenAI' ? has(self.openAI) : !has(self.openAI)",message="openAI is required when type is OpenAI, and forbidden otherwise" +kubebuilder:validation:XValidation:rule="self.type == 'AzureOpenAI' ? has(self.azureOpenAI) : !has(self.azureOpenAI)",message="azureOpenAI is required when type is AzureOpenAI, and forbidden otherwise" +kubebuilder:validation:XValidation:rule="self.type == 'AWSBedrock' ? has(self.awsBedrock) : !has(self.awsBedrock)",message="awsBedrock is required when type is AWSBedrock, and forbidden otherwise"

func (*LLMProviderSpec) DeepCopy

func (in *LLMProviderSpec) DeepCopy() *LLMProviderSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LLMProviderSpec.

func (*LLMProviderSpec) DeepCopyInto

func (in *LLMProviderSpec) DeepCopyInto(out *LLMProviderSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type LLMProviderType

type LLMProviderType string

LLMProviderType identifies the hosting backend for an LLM provider.

Each backend has different authentication requirements and API endpoints. The type field acts as the discriminator for a union: exactly one of the per-provider configuration fields must be set, matching the type value.

Allowed values:

  • "Anthropic" — Direct Anthropic API.
  • "GoogleCloudVertex" — Google Cloud Vertex AI.
  • "OpenAI" — OpenAI-compatible API.
  • "AzureOpenAI" — Azure OpenAI Service.
  • "AWSBedrock" — AWS Bedrock.

+kubebuilder:validation:Enum=Anthropic;GoogleCloudVertex;OpenAI;AzureOpenAI;AWSBedrock

const (
	// LLMProviderAnthropic uses the Anthropic API directly.
	LLMProviderAnthropic LLMProviderType = "Anthropic"
	// LLMProviderGoogleCloudVertex uses Google Cloud Vertex AI as the LLM backend.
	LLMProviderGoogleCloudVertex LLMProviderType = "GoogleCloudVertex"
	// LLMProviderOpenAI uses an OpenAI-compatible API endpoint.
	LLMProviderOpenAI LLMProviderType = "OpenAI"
	// LLMProviderAzureOpenAI uses the Azure OpenAI Service.
	LLMProviderAzureOpenAI LLMProviderType = "AzureOpenAI"
	// LLMProviderAWSBedrock uses AWS Bedrock.
	LLMProviderAWSBedrock LLMProviderType = "AWSBedrock"
)

type MCPHeader

type MCPHeader struct {
	// name of the header (e.g., "Authorization", "X-API-Key").
	// Must be at least 1 character, containing only letters, digits, and hyphens.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	// +kubebuilder:validation:XValidation:rule="self.matches('^[A-Za-z][A-Za-z0-9-]*$')",message="name must start with a letter and contain only letters, digits, and hyphens"
	Name string `json:"name,omitempty"`

	// valueFrom is the source of the header value.
	// +required
	ValueFrom MCPHeaderValueSource `json:"valueFrom,omitzero"`
}

MCPHeader defines an HTTP header to send with every request to an MCP server. Used for authentication and routing.

func (*MCPHeader) DeepCopy

func (in *MCPHeader) DeepCopy() *MCPHeader

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MCPHeader.

func (*MCPHeader) DeepCopyInto

func (in *MCPHeader) DeepCopyInto(out *MCPHeader)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type MCPHeaderSourceType

type MCPHeaderSourceType string

MCPHeaderSourceType defines how a header value is sourced when the operator configures MCP server connections for an agent.

  • "Secret" — The value is read from a Kubernetes Secret referenced by the secret field. Use this for API keys and tokens.
  • "ServiceAccountToken" — The operator injects a Kubernetes service account token automatically (for MCP servers that accept K8s auth).
  • "Client" — The value is provided by the calling client at runtime (e.g., forwarded from a user session).

+kubebuilder:validation:Enum=Secret;ServiceAccountToken;Client

const (
	// MCPHeaderSourceTypeSecret reads the header value from a Kubernetes Secret.
	MCPHeaderSourceTypeSecret MCPHeaderSourceType = "Secret"
	// MCPHeaderSourceTypeServiceAccountToken uses an auto-injected Kubernetes SA token.
	MCPHeaderSourceTypeServiceAccountToken MCPHeaderSourceType = "ServiceAccountToken"
	// MCPHeaderSourceTypeClient expects the value to be provided by the caller.
	MCPHeaderSourceTypeClient MCPHeaderSourceType = "Client"
)

type MCPHeaderValueSource

type MCPHeaderValueSource struct {
	// type specifies the source type for the header value. Allowed values:
	//   - "Secret"     — reads the value from a Kubernetes Secret (use for
	//     API keys and tokens). Requires the secret field to be set.
	//   - "ServiceAccountToken" — auto-injects a Kubernetes service account token
	//     (for MCP servers that accept K8s auth).
	//   - "Client"     — the value is provided by the calling client at
	//     runtime (e.g., forwarded from a user session).
	// +required
	Type MCPHeaderSourceType `json:"type,omitempty"`

	// secret references a Secret containing the header value.
	// Required when type is "Secret".
	// +optional
	Secret SecretReference `json:"secret,omitzero"`
}

MCPHeaderValueSource defines where to obtain the value for an MCP header. Exactly one source is used depending on the type field. +kubebuilder:validation:XValidation:rule="self.type == 'Secret' ? has(self.secret) : !has(self.secret)",message="secret is required when type is Secret, and forbidden otherwise"

func (*MCPHeaderValueSource) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MCPHeaderValueSource.

func (*MCPHeaderValueSource) DeepCopyInto

func (in *MCPHeaderValueSource) DeepCopyInto(out *MCPHeaderValueSource)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type MCPServerConfig

type MCPServerConfig struct {
	// name of the MCP server. Must start with a letter and contain only
	// lowercase alphanumeric characters and hyphens. Must be 1-253 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	// +kubebuilder:validation:XValidation:rule="self.matches('^[a-z][a-z0-9-]*$')",message="name must start with a lowercase letter and contain only lowercase alphanumerics and hyphens"
	Name string `json:"name,omitempty"`

	// url of the MCP server (HTTP/HTTPS). Must be an HTTP or HTTPS URL,
	// maximum 2048 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=2048
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getScheme() in ['http', 'https']",message="url must be a valid HTTP or HTTPS URL"
	URL string `json:"url,omitempty"`

	// timeoutSeconds is the per-request timeout for calls to this MCP server,
	// in seconds. Default is 5.
	// Valid range: 1-300.
	// +optional
	// +default=5
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=300
	TimeoutSeconds int32 `json:"timeoutSeconds,omitempty"`

	// headers to send to the MCP server. Maximum 20 items.
	// +optional
	// +listType=map
	// +listMapKey=name
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=20
	Headers []MCPHeader `json:"headers,omitempty"`
}

MCPServerConfig defines the configuration for an MCP (Model Context Protocol) server that the agent can connect to for additional tools and context. MCP servers extend the agent's capabilities beyond its built-in skills.

Example — connecting to an OpenShift MCP server with SA token auth:

mcpServers:
  - name: openshift
    url: https://mcp.openshift-lightspeed.svc:8443/sse
    timeoutSeconds: 10
    headers:
      - name: Authorization
        valueFrom:
          type: ServiceAccountToken

Example — connecting to an external API with secret-based auth:

mcpServers:
  - name: pagerduty
    url: https://mcp-pagerduty.example.com/sse
    headers:
      - name: X-API-Key
        valueFrom:
          type: Secret
          secret:
            name: pagerduty-api-key

func (*MCPServerConfig) DeepCopy

func (in *MCPServerConfig) DeepCopy() *MCPServerConfig

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MCPServerConfig.

func (*MCPServerConfig) DeepCopyInto

func (in *MCPServerConfig) DeepCopyInto(out *MCPServerConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type OpenAIConfig

type OpenAIConfig struct {
	// credentialsSecret references a Secret in the operator namespace
	// (openshift-lightspeed) containing the OpenAI API credentials.
	// The Secret must contain the key OPENAI_API_KEY.
	// +required
	CredentialsSecret SecretReference `json:"credentialsSecret,omitzero"`

	// url is an optional override for the OpenAI API endpoint.
	// Only needed for custom deployments or API proxies.
	// Must be a valid HTTP or HTTPS URL with a hostname. Paths and query
	// parameters are allowed. Fragments and userinfo are not permitted.
	// Maximum 2048 characters.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=2048
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getScheme() in ['http', 'https']",message="must use http or https scheme"
	// +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getHostname() != ”",message="must include a hostname"
	// +kubebuilder:validation:XValidation:rule="!self.contains('@')",message="userinfo is not allowed in URL"
	// +kubebuilder:validation:XValidation:rule="!self.contains('#')",message="fragments are not allowed in URL"
	URL string `json:"url,omitempty"`
}

OpenAIConfig contains configuration for an OpenAI-compatible API provider.

func (*OpenAIConfig) DeepCopy

func (in *OpenAIConfig) DeepCopy() *OpenAIConfig

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenAIConfig.

func (*OpenAIConfig) DeepCopyInto

func (in *OpenAIConfig) DeepCopyInto(out *OpenAIConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type Proposal

type Proposal struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is the standard object metadata.
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty"`

	// spec defines the desired state of Proposal.
	// +required
	Spec ProposalSpec `json:"spec,omitzero"`

	// status defines the observed state of Proposal.
	// +optional
	Status ProposalStatus `json:"status,omitzero"`
}

Proposal represents a unit of work managed by the agentic platform. It is the primary resource component teams and adapters interact with.

A Proposal defines the workflow shape inline: which steps run and which agent handles each step. Analysis is always required. Omit execution and/or verification to skip those steps.

Example — analysis only (advisory):

apiVersion: agentic.openshift.io/v1alpha1
kind: Proposal
metadata:
  name: one-off-investigation
spec:
  request: "Investigate why pod foo is crashlooping"
  targetNamespaces:
    - lightspeed-demo
  tools:
    skills:
      - image: registry.redhat.io/acs/acs-agentic-skills:latest
  analysis:
    agent: smart

Example — full remediation (analyze → execute → verify):

apiVersion: agentic.openshift.io/v1alpha1
kind: Proposal
metadata:
  name: fix-nginx-cve-2024-1234
  namespace: stackrox
spec:
  request: "Fix CVE-2024-1234 in nginx:1.21"
  targetNamespaces:
    - lightspeed-demo
  tools:
    skills:
      - image: registry.redhat.io/acs/acs-agentic-skills:latest
    requiredSecrets:
      - name: acs-api-token
        mountAs:
          type: EnvVar
          envVar:
            name: ACS_API_TOKEN
  analysis:
    agent: smart
  execution: {}
  verification:
    agent: fast

func (*Proposal) DeepCopy

func (in *Proposal) DeepCopy() *Proposal

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Proposal.

func (*Proposal) DeepCopyInto

func (in *Proposal) DeepCopyInto(out *Proposal)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*Proposal) DeepCopyObject

func (in *Proposal) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type ProposalApproval

type ProposalApproval struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is the standard object metadata.
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty"`

	// spec defines the desired approval state.
	// +optional
	Spec ProposalApprovalSpec `json:"spec,omitzero"`

	// status defines the observed approval state.
	// +optional
	Status ProposalApprovalStatus `json:"status,omitzero"`
}

ProposalApproval tracks per-step approval state for a Proposal. The operator creates it when a Proposal is created. Users update it to approve or deny individual workflow steps.

ProposalApproval has a 1:1 relationship with its Proposal (same name, same namespace) and is owned by the Proposal via an owner reference for garbage collection.

Example:

apiVersion: agentic.openshift.io/v1alpha1
kind: ProposalApproval
metadata:
  name: fix-crash
  namespace: my-namespace
  ownerReferences:
    - apiVersion: agentic.openshift.io/v1alpha1
      kind: Proposal
      name: fix-crash
spec:
  stages:
    - type: Analysis
      analysis: {}
    - type: Execution
      execution:
        option: 0
        agent: fast

func (*ProposalApproval) DeepCopy

func (in *ProposalApproval) DeepCopy() *ProposalApproval

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProposalApproval.

func (*ProposalApproval) DeepCopyInto

func (in *ProposalApproval) DeepCopyInto(out *ProposalApproval)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ProposalApproval) DeepCopyObject

func (in *ProposalApproval) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type ProposalApprovalList

type ProposalApprovalList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []ProposalApproval `json:"items"`
}

ProposalApprovalList contains a list of ProposalApproval.

func (*ProposalApprovalList) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProposalApprovalList.

func (*ProposalApprovalList) DeepCopyInto

func (in *ProposalApprovalList) DeepCopyInto(out *ProposalApprovalList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ProposalApprovalList) DeepCopyObject

func (in *ProposalApprovalList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type ProposalApprovalSpec

type ProposalApprovalSpec struct {
	// stages lists the approved (or denied) workflow steps. Each entry is
	// a discriminated union keyed by type. Users add stages one at a time
	// via patch as they approve each step.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=4
	Stages []ApprovalStage `json:"stages,omitempty"`
}

ProposalApprovalSpec defines the desired state of ProposalApproval.

spec.stages is append-only: once a stage is added, it cannot be removed. Decisions once set cannot be changed. maxAttempts once set cannot be reduced.

+kubebuilder:validation:XValidation:rule="oldSelf.stages.all(old, self.stages.exists(s, s.type == old.type))",message="stages are append-only: existing stages cannot be removed" +kubebuilder:validation:XValidation:rule="oldSelf.stages.all(old, !(has(old.decision) && old.decision == 'Denied') || self.stages.exists(s, s.type == old.type && has(s.decision) && s.decision == 'Denied'))",message="decisions once set cannot be changed" +kubebuilder:validation:XValidation:rule="oldSelf.stages.all(old, old.type != 'Execution' || !has(old.execution) || !has(old.execution.maxAttempts) || old.execution.maxAttempts == 0 || self.stages.exists(s, s.type == 'Execution' && has(s.execution) && has(s.execution.maxAttempts) && s.execution.maxAttempts == old.execution.maxAttempts))",message="maxAttempts once set cannot be changed" +kubebuilder:validation:MinProperties=1

func (*ProposalApprovalSpec) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProposalApprovalSpec.

func (*ProposalApprovalSpec) DeepCopyInto

func (in *ProposalApprovalSpec) DeepCopyInto(out *ProposalApprovalSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ProposalApprovalStatus

type ProposalApprovalStatus struct {
	// stages contains the per-stage approval status set by the controller.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=4
	Stages []ApprovalStageStatus `json:"stages,omitempty"`
}

ProposalApprovalStatus defines the observed state of ProposalApproval.

+kubebuilder:validation:MinProperties=1

func (*ProposalApprovalStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProposalApprovalStatus.

func (*ProposalApprovalStatus) DeepCopyInto

func (in *ProposalApprovalStatus) DeepCopyInto(out *ProposalApprovalStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ProposalList

type ProposalList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []Proposal `json:"items"`
}

ProposalList contains a list of Proposal.

func (*ProposalList) DeepCopy

func (in *ProposalList) DeepCopy() *ProposalList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProposalList.

func (*ProposalList) DeepCopyInto

func (in *ProposalList) DeepCopyInto(out *ProposalList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ProposalList) DeepCopyObject

func (in *ProposalList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type ProposalPhase

type ProposalPhase string

ProposalPhase summarizes the proposal's lifecycle state for display. This type is used internally by the controller, CLI, and console to derive a human-friendly phase from conditions. It is NOT stored on the CRD status — use DerivePhase(conditions) to compute it.

const (
	ProposalPhasePending    ProposalPhase = "Pending"
	ProposalPhaseAnalyzing  ProposalPhase = "Analyzing"
	ProposalPhaseProposed   ProposalPhase = "Proposed"
	ProposalPhaseExecuting  ProposalPhase = "Executing"
	ProposalPhaseVerifying  ProposalPhase = "Verifying"
	ProposalPhaseCompleted  ProposalPhase = "Completed"
	ProposalPhaseFailed     ProposalPhase = "Failed"
	ProposalPhaseDenied     ProposalPhase = "Denied"
	ProposalPhaseEscalating ProposalPhase = "Escalating"
	ProposalPhaseEscalated  ProposalPhase = "Escalated"
)

func DerivePhase

func DerivePhase(conditions []metav1.Condition) ProposalPhase

DerivePhase computes the display phase from conditions. Conditions are the source of truth; this function maps them to a human-friendly phase for display in CLI, console, and controller routing. SYNC: must match derivePhaseFromConditions in lightspeed-agentic-console/src/models/proposal.ts

type ProposalResult

type ProposalResult struct {
	// description is a Markdown-formatted summary of the overall remediation
	// approach. Maximum 8192 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=8192
	Description string `json:"description,omitempty"`
	// actions is the ordered list of discrete actions the agent proposes.
	// Maximum 50 items.
	// +required
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=50
	Actions []ProposedAction `json:"actions,omitempty"`
	// risk is the agent's assessment of how risky the remediation is.
	// Critical-risk proposals typically require explicit human review.
	// +required
	Risk RiskLevel `json:"risk,omitempty"`
	// reversible indicates whether the remediation can be rolled back
	// if something goes wrong. See rollbackPlan for details.
	// Must be one of: Reversible, Irreversible, Partial.
	// +optional
	Reversible Reversibility `json:"reversible,omitempty"`
	// estimatedImpact is a Markdown-formatted description of the expected
	// impact of the remediation on the system
	// (e.g., "Brief pod restart, ~30s downtime").
	// Maximum 1024 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=1024
	EstimatedImpact string `json:"estimatedImpact,omitempty"`
	// rollbackPlan describes how to undo the remediation if execution fails
	// or causes unexpected issues. Only the execution step mutates cluster
	// state, so rollback lives here alongside the actions it would undo.
	// +optional
	RollbackPlan RollbackPlan `json:"rollbackPlan,omitzero"`
}

ProposalResult contains the remediation plan from the analysis agent. This is part of a RemediationOption and is presented to the user after analysis, before approval. The risk and reversibility assessments help users make informed approval decisions.

func (*ProposalResult) DeepCopy

func (in *ProposalResult) DeepCopy() *ProposalResult

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProposalResult.

func (*ProposalResult) DeepCopyInto

func (in *ProposalResult) DeepCopyInto(out *ProposalResult)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ProposalSpec

type ProposalSpec struct {
	// request is the user's original request, alert description, or a
	// description of what triggered this proposal. This text is passed to
	// the analysis agent as the primary input.
	//
	// Immutable: Proposals are run-to-completion (like Jobs). To change
	// the request, create a new Proposal. Use spec.revisionFeedback for
	// iterative feedback on an existing analysis.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=32768
	// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="request is immutable after creation"
	Request string `json:"request,omitempty"`

	// targetNamespaces are the Kubernetes namespace(s) this proposal
	// operates on. Used for RBAC scoping and context to the analysis agent.
	//
	// When omitted, the proposal is not namespace-scoped — the analysis
	// agent determines the relevant namespaces from the request context.
	// Adapters (AlertManager, ACS) typically set this automatically from
	// the source event.
	//
	// Immutable: RBAC scoping is fixed at creation. Changing target
	// namespaces mid-flight would invalidate the analysis and any
	// granted execution RBAC.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=50
	// +kubebuilder:validation:XValidation:rule="self.all(ns, !format.dns1123Label().validate(ns).hasValue())",message="each namespace must be a valid DNS label"
	// +kubebuilder:validation:items:MinLength=1
	// +kubebuilder:validation:items:MaxLength=63
	TargetNamespaces []string `json:"targetNamespaces,omitempty"`

	// analysisOutput configures the analysis step's structured output.
	// The mode field controls which built-in properties are included
	// (Default: all; Minimal: only title). The schema field optionally
	// defines adapter-specific structured data injected as "components".
	//
	// When omitted, the analysis uses the full default schema with all
	// built-in properties and no custom components.
	//
	// Immutable: the output contract is fixed at creation.
	// +optional
	AnalysisOutput AnalysisOutput `json:"analysisOutput,omitzero"`

	// tools defines the default tools for all steps: skills images,
	// MCP servers, and required secrets. Per-step tools
	// (analysis.tools, execution.tools, verification.tools) replace
	// this default for individual steps.
	//
	// Immutable: the skills and secrets available to the agent are
	// fixed at creation. Changing tools mid-flight could violate the
	// assumptions of an in-progress analysis or execution.
	// +optional
	Tools ToolsSpec `json:"tools,omitzero"`

	// analysis defines per-step configuration for the analysis step,
	// including which agent handles it and any per-step tools.
	//
	// Immutable: agent and per-step tools are fixed at creation.
	// +required
	Analysis ProposalStep `json:"analysis,omitzero"`

	// execution defines per-step configuration for the execution step.
	// Omit to skip execution (advisory/assisted patterns).
	//
	// Immutable: agent and per-step tools are fixed at creation.
	// +optional
	Execution ProposalStep `json:"execution,omitzero"`

	// verification defines per-step configuration for the verification step.
	// Omit to skip verification.
	//
	// Immutable: agent and per-step tools are fixed at creation.
	// +optional
	Verification ProposalStep `json:"verification,omitzero"`

	// revisionFeedback is the user's free-text feedback requesting changes
	// to the analysis. Patching this field bumps metadata.generation, which
	// the operator detects (generation > observedGeneration) and triggers
	// re-analysis with the feedback appended to the original request.
	//
	// Mutable: this is the only mutable spec field. All other spec fields
	// are immutable via CEL rules, so generation changes signal revision.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=32768
	RevisionFeedback string `json:"revisionFeedback,omitempty"`
}

ProposalSpec defines the desired state of Proposal.

A Proposal defines the workflow shape inline, specifying which steps run and which agent handles each step. Analysis is always required. Omit execution and/or verification to skip those steps.

+kubebuilder:validation:XValidation:rule="has(self.analysis)",message="analysis must be provided" +kubebuilder:validation:XValidation:rule="!has(oldSelf.targetNamespaces) || (has(self.targetNamespaces) && self.targetNamespaces == oldSelf.targetNamespaces)",message="targetNamespaces is immutable once set" +kubebuilder:validation:XValidation:rule="!has(oldSelf.analysisOutput) || (has(self.analysisOutput) && self.analysisOutput == oldSelf.analysisOutput)",message="analysisOutput is immutable once set" +kubebuilder:validation:XValidation:rule="!has(self.analysisOutput) || self.analysisOutput.mode != 'Minimal' || (!has(self.execution) && !has(self.verification))",message="analysisOutput mode Minimal is only allowed for analysis-only proposals (no execution or verification steps)" +kubebuilder:validation:XValidation:rule="!has(oldSelf.tools) || (has(self.tools) && self.tools == oldSelf.tools)",message="tools is immutable once set" +kubebuilder:validation:XValidation:rule="!has(oldSelf.analysis) || (has(self.analysis) && self.analysis == oldSelf.analysis)",message="analysis is immutable once set" +kubebuilder:validation:XValidation:rule="!has(oldSelf.execution) || (has(self.execution) && self.execution == oldSelf.execution)",message="execution is immutable once set" +kubebuilder:validation:XValidation:rule="!has(oldSelf.verification) || (has(self.verification) && self.verification == oldSelf.verification)",message="verification is immutable once set"

func (*ProposalSpec) DeepCopy

func (in *ProposalSpec) DeepCopy() *ProposalSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProposalSpec.

func (*ProposalSpec) DeepCopyInto

func (in *ProposalSpec) DeepCopyInto(out *ProposalSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ProposalStatus

type ProposalStatus struct {
	// conditions represent the latest available observations using the
	// standard Kubernetes condition pattern. Condition types include:
	// Analyzed, Approved, Executed, Verified, and Escalated.
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	// +optional
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=8
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`

	// steps contains the per-step observed state (analysis, execution,
	// verification). Each step independently tracks its timing, sandbox
	// info, and references to result CRs.
	// +optional
	Steps StepsStatus `json:"steps,omitzero"`
}

ProposalStatus defines the observed state of Proposal. All fields are set by the operator -- users should not modify status fields directly. The status provides complete observability into the proposal's progress, including per-step results, retry history, and standard Kubernetes conditions. An empty status (`status: {}`) is the initial state before the operator's first reconcile.

+kubebuilder:validation:MinProperties=1

func (*ProposalStatus) DeepCopy

func (in *ProposalStatus) DeepCopy() *ProposalStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProposalStatus.

func (*ProposalStatus) DeepCopyInto

func (in *ProposalStatus) DeepCopyInto(out *ProposalStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ProposalStep

type ProposalStep struct {
	// agent is the name of the cluster-scoped Agent CR to use for this step.
	// Defaults to "default" when omitted.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	// +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="must be a valid DNS subdomain: lowercase alphanumeric characters, hyphens, and dots"
	Agent string `json:"agent,omitempty"`

	// tools provides per-step tools that replace the shared spec.tools
	// for this step. Use this when different steps need different skills.
	// +optional
	Tools ToolsSpec `json:"tools,omitzero"`
}

ProposalStep defines per-step configuration on a Proposal. The agent field selects which cluster-scoped Agent CR handles this step. The tools field provides per-step tools that replace the shared spec.tools. +kubebuilder:validation:MinProperties=1

func (*ProposalStep) DeepCopy

func (in *ProposalStep) DeepCopy() *ProposalStep

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProposalStep.

func (*ProposalStep) DeepCopyInto

func (in *ProposalStep) DeepCopyInto(out *ProposalStep)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (ProposalStep) IsZero

func (s ProposalStep) IsZero() bool

type ProposedAction

type ProposedAction struct {
	// type is the action category (e.g., "patch", "scale", "restart",
	// "create", "delete", "rollout"). Free-form string to allow agents
	// to express domain-specific action types. Must be 1-256 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=256
	Type string `json:"type,omitempty"`
	// description is a Markdown-formatted explanation of what this action
	// will do (e.g., "Increase memory limit from 256Mi to 512Mi").
	// Maximum 4096 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=4096
	Description string `json:"description,omitempty"`
}

ProposedAction describes a single discrete action the analysis agent recommends as part of its remediation plan. Actions are displayed to the user after analysis for review before approval.

func (*ProposedAction) DeepCopy

func (in *ProposedAction) DeepCopy() *ProposedAction

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProposedAction.

func (*ProposedAction) DeepCopyInto

func (in *ProposedAction) DeepCopyInto(out *ProposedAction)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type RBACResult

type RBACResult struct {
	// namespaceScoped are rules that will be applied via Role + RoleBinding
	// in the proposal's target namespaces. These are the most common rules.
	// Maximum 50 items.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=50
	NamespaceScoped []RBACRule `json:"namespaceScoped,omitempty"`
	// clusterScoped are rules that will be applied via ClusterRole +
	// ClusterRoleBinding. Used when the agent needs cross-namespace or
	// non-namespaced resource access (e.g., reading nodes, CRDs).
	// Maximum 50 items.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=50
	ClusterScoped []RBACRule `json:"clusterScoped,omitempty"`
}

RBACResult contains the RBAC permissions requested by the analysis agent for the execution step. The operator creates a dedicated ServiceAccount per proposal and binds these permissions via Role (namespace-scoped) or ClusterRole (cluster-scoped) before launching the execution sandbox. All RBAC resources are cleaned up after the proposal reaches a terminal state.

+kubebuilder:validation:MinProperties=1

func (*RBACResult) DeepCopy

func (in *RBACResult) DeepCopy() *RBACResult

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RBACResult.

func (*RBACResult) DeepCopyInto

func (in *RBACResult) DeepCopyInto(out *RBACResult)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type RBACRule

type RBACRule struct {
	// namespace is the target namespace for namespace-scoped rules.
	// Must match one of the proposal's targetNamespaces. Ignored for
	// cluster-scoped rules. Validation is deferred to the operator's
	// policy engine at runtime. Must be a valid RFC 1123 DNS label.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=63
	// +kubebuilder:validation:XValidation:rule="!format.dns1123Label().validate(self).hasValue()",message="must be a valid DNS label: lowercase alphanumeric characters and hyphens, starting with an alphabetic character and ending with an alphanumeric character"
	Namespace string `json:"namespace,omitempty"`
	// apiGroups are the API groups for this rule (e.g., "", "apps", "batch").
	// The empty string "" represents the core API group (pods, services, etc.).
	// Maximum 20 items, each up to 253 characters.
	// +required
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=20
	// +kubebuilder:validation:items:MaxLength=253
	APIGroups []string `json:"apiGroups,omitempty"` //nolint:kubeapilinter // empty string "" is a valid core API group
	// resources are the resource types (e.g., "pods", "deployments").
	// Maximum 20 items.
	// +required
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=20
	// +kubebuilder:validation:items:MinLength=1
	// +kubebuilder:validation:items:MaxLength=253
	Resources []string `json:"resources,omitempty"`
	// resourceNames restricts the rule to specific named resources.
	// When empty, the rule applies to all resources of the given type.
	// Maximum 50 items.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=50
	// +kubebuilder:validation:items:MinLength=1
	// +kubebuilder:validation:items:MaxLength=253
	ResourceNames []string `json:"resourceNames,omitempty"`
	// verbs are the allowed operations (e.g., "get", "patch", "delete").
	// Maximum 10 items.
	// +required
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=10
	// +kubebuilder:validation:items:MinLength=1
	// +kubebuilder:validation:items:MaxLength=63
	Verbs []string `json:"verbs,omitempty"`
	// justification is a Markdown-formatted explanation of why this
	// permission is needed for the remediation
	// (e.g., "Need to patch deployment to increase memory limit").
	// Required for audit and policy enforcement. Maximum 1024 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=1024
	Justification string `json:"justification,omitempty"`
}

RBACRule describes a single RBAC permission that the analysis agent requests for the execution step. The operator's policy engine validates these requests against a 6-layer defense model before creating the actual Role/ClusterRole bindings. Each rule must include a justification so that users and policy can audit why the permission is needed.

func (*RBACRule) DeepCopy

func (in *RBACRule) DeepCopy() *RBACRule

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RBACRule.

func (*RBACRule) DeepCopyInto

func (in *RBACRule) DeepCopyInto(out *RBACRule)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type RemediationOption

type RemediationOption struct {
	// title is a short Markdown-formatted name for this option
	// (e.g., "Increase memory limit", "Restart with backoff").
	// Must be 1-256 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=256
	Title string `json:"title,omitempty"`
	// summary is an optional Markdown-formatted one-line summary for
	// collapsed views in the console UI. Maximum 1024 characters.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=1024
	Summary string `json:"summary,omitempty"`
	// diagnosis contains the root cause analysis specific to this option.
	// Present when analysisOutput mode is Default (or omitted). Omitted
	// when mode is Minimal.
	// +optional
	Diagnosis DiagnosisResult `json:"diagnosis,omitzero"`
	// proposal contains the remediation plan for this option.
	// Present when analysisOutput mode is Default (or omitted). Omitted
	// when mode is Minimal without an execution step.
	// +optional
	Proposal ProposalResult `json:"proposal,omitzero"`
	// verification contains the verification plan. Omitted when
	// verification is skipped in the workflow.
	// +optional
	Verification VerificationPlan `json:"verification,omitzero"`
	// rbac contains the RBAC permissions the execution agent will need.
	// The operator's policy engine validates these before creating the
	// actual Kubernetes RBAC resources. Omitted for advisory-only options.
	// +optional
	RBAC RBACResult `json:"rbac,omitzero"`
	// components contains optional adapter-defined structured data whose
	// shape is determined by spec.analysisOutput.schema on the Proposal.
	// The operator passes this through to the AnalysisResult CR; the
	// console renders it using adapter-specific UI components.
	// +optional
	// +kubebuilder:validation:Schemaless
	// +kubebuilder:pruning:PreserveUnknownFields
	Components *apiextensionsv1.JSON `json:"components,omitempty"`
}

RemediationOption represents a single remediation approach produced by the analysis agent. The agent may return multiple options, each with its own diagnosis, remediation plan, verification strategy, and RBAC requirements. When the user approves execution, the operator trims the AnalysisResult to keep only the approved option and uses its RBAC and plan for the execution step.

The components field is an extensibility point for adapter-specific UI data. For example, an ACS adapter might include violation details or affected deployment information as components that the console plugin renders with custom components.

+kubebuilder:validation:XValidation:rule="!has(self.diagnosis) || has(self.proposal)",message="proposal is required when diagnosis is present" +kubebuilder:validation:XValidation:rule="!has(self.proposal) || has(self.diagnosis)",message="diagnosis is required when proposal is present"

func (*RemediationOption) DeepCopy

func (in *RemediationOption) DeepCopy() *RemediationOption

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RemediationOption.

func (*RemediationOption) DeepCopyInto

func (in *RemediationOption) DeepCopyInto(out *RemediationOption)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type Reversibility

type Reversibility string

Reversibility indicates whether a remediation can be rolled back. +kubebuilder:validation:Enum=Reversible;Irreversible;Partial

const (
	ReversibilityReversible   Reversibility = "Reversible"
	ReversibilityIrreversible Reversibility = "Irreversible"
	ReversibilityPartial      Reversibility = "Partial"
)

type RiskLevel

type RiskLevel string

RiskLevel is the agent's assessment of how risky a remediation is. Critical-risk proposals typically require explicit human review.

  • "Low" — Minimal risk; safe to apply automatically.
  • "Medium" — Moderate risk; review recommended.
  • "High" — Significant risk; careful review required.
  • "Critical" — Extreme risk; manual approval strongly recommended.

+kubebuilder:validation:Enum=Low;Medium;High;Critical

const (
	RiskLevelLow      RiskLevel = "Low"
	RiskLevelMedium   RiskLevel = "Medium"
	RiskLevelHigh     RiskLevel = "High"
	RiskLevelCritical RiskLevel = "Critical"
)

type RollbackPlan

type RollbackPlan struct {
	// description is a Markdown-formatted explanation of the rollback strategy.
	// Must be 1-4096 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=4096
	Description string `json:"description,omitempty"`
	// command is the rollback command or steps to execute.
	// Maximum 4096 characters.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=4096
	Command string `json:"command,omitempty"`
}

RollbackPlan describes how to undo the remediation if execution fails or causes unexpected issues. Populated by the analysis agent.

func (*RollbackPlan) DeepCopy

func (in *RollbackPlan) DeepCopy() *RollbackPlan

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollbackPlan.

func (*RollbackPlan) DeepCopyInto

func (in *RollbackPlan) DeepCopyInto(out *RollbackPlan)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type SandboxInfo

type SandboxInfo struct {
	// claimName is the name of the SandboxClaim resource that owns the
	// sandbox pod. Maximum 253 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	ClaimName string `json:"claimName,omitempty"`
	// namespace is the namespace where the SandboxClaim and its pod live.
	// Must be a valid RFC 1123 DNS label.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=63
	// +kubebuilder:validation:XValidation:rule="!format.dns1123Label().validate(self).hasValue()",message="must be a valid DNS label: lowercase alphanumeric characters and hyphens, starting with an alphabetic character and ending with an alphanumeric character"
	Namespace string `json:"namespace,omitempty"`
}

SandboxInfo tracks the sandbox pod used for a workflow step. The operator creates a sandbox pod for each active step (analysis, execution, verification) and records the claim details here. This enables the console UI to stream sandbox pod logs in real time.

func (*SandboxInfo) DeepCopy

func (in *SandboxInfo) DeepCopy() *SandboxInfo

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SandboxInfo.

func (*SandboxInfo) DeepCopyInto

func (in *SandboxInfo) DeepCopyInto(out *SandboxInfo)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type SandboxStep

type SandboxStep string

SandboxStep identifies which workflow step a sandbox pod is running for. Used in PreviousAttempt to record which step failed, and internally by the operator for sandbox lifecycle management. +kubebuilder:validation:Enum=Analysis;Execution;Verification;Escalation

const (
	// SandboxStepAnalysis is the analysis step sandbox.
	SandboxStepAnalysis SandboxStep = "Analysis"
	// SandboxStepExecution is the execution step sandbox.
	SandboxStepExecution SandboxStep = "Execution"
	// SandboxStepVerification is the verification step sandbox.
	SandboxStepVerification SandboxStep = "Verification"
	// SandboxStepEscalation is the escalation step sandbox.
	SandboxStepEscalation SandboxStep = "Escalation"
)

type SecretMountEnvVarConfig

type SecretMountEnvVarConfig struct {
	// name is the environment variable name (e.g., "GITHUB_TOKEN").
	// Must be uppercase letters, digits, and underscores, starting
	// with a letter or underscore.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=256
	// +kubebuilder:validation:XValidation:rule="self.matches('^[A-Z_][A-Z0-9_]*$')",message="must be a valid environment variable name: uppercase letters, digits, and underscores, starting with a letter or underscore"
	Name string `json:"name,omitempty"`
}

SecretMountEnvVarConfig specifies the environment variable name to inject the secret value as.

func (*SecretMountEnvVarConfig) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretMountEnvVarConfig.

func (*SecretMountEnvVarConfig) DeepCopyInto

func (in *SecretMountEnvVarConfig) DeepCopyInto(out *SecretMountEnvVarConfig)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type SecretMountFilePathConfig

type SecretMountFilePathConfig struct {
	// path is the absolute file path (e.g., "/etc/secrets/tls.crt").
	// Must start with a forward slash.
	// +required
	// +kubebuilder:validation:MinLength=2
	// +kubebuilder:validation:MaxLength=512
	// +kubebuilder:validation:XValidation:rule="self.startsWith('/')",message="path must be an absolute path starting with '/'"
	Path string `json:"path,omitempty"`
}

SecretMountFilePathConfig specifies the file path where the secret value is mounted.

func (*SecretMountFilePathConfig) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretMountFilePathConfig.

func (*SecretMountFilePathConfig) DeepCopyInto

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type SecretMountSpec

type SecretMountSpec struct {
	// type specifies how the secret is exposed. Allowed values: "EnvVar",
	// "FilePath".
	//
	// When set to EnvVar, the secret value is injected as an environment
	// variable, and the 'envVar' field must be configured.
	//
	// When set to FilePath, the secret is mounted as a file, and the
	// 'filePath' field must be configured.
	// +required
	Type SecretMountType `json:"type,omitempty"`

	// envVar configures environment variable injection.
	// Required when type is "EnvVar".
	// +optional
	EnvVar SecretMountEnvVarConfig `json:"envVar,omitzero"`

	// filePath configures file mount.
	// Required when type is "FilePath".
	// +optional
	FilePath SecretMountFilePathConfig `json:"filePath,omitzero"`
}

SecretMountSpec specifies how a secret is exposed in the sandbox pod. The type field is the discriminator: exactly one of envVar or filePath must be set, matching the type value.

+kubebuilder:validation:XValidation:rule="self.type == 'EnvVar' ? has(self.envVar) : !has(self.envVar)",message="envVar is required when type is EnvVar, and forbidden otherwise" +kubebuilder:validation:XValidation:rule="self.type == 'FilePath' ? has(self.filePath) : !has(self.filePath)",message="filePath is required when type is FilePath, and forbidden otherwise"

func (*SecretMountSpec) DeepCopy

func (in *SecretMountSpec) DeepCopy() *SecretMountSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretMountSpec.

func (*SecretMountSpec) DeepCopyInto

func (in *SecretMountSpec) DeepCopyInto(out *SecretMountSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type SecretMountType

type SecretMountType string

SecretMountType specifies how a secret is exposed in the sandbox pod.

Allowed values:

  • "EnvVar" — inject the secret value as an environment variable.
  • "FilePath" — mount the secret as a file at a given path.

+kubebuilder:validation:Enum=EnvVar;FilePath

const (
	SecretMountEnvVar   SecretMountType = "EnvVar"
	SecretMountFilePath SecretMountType = "FilePath"
)

type SecretReference

type SecretReference struct {
	// name of the Secret. Must be a valid RFC 1123 DNS subdomain.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	// +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="must be a valid DNS subdomain: lowercase alphanumeric characters, hyphens, and dots"
	Name string `json:"name,omitempty"`
}

SecretReference references a Kubernetes Secret by name within the same namespace. Used for credentials and authentication tokens.

func (*SecretReference) DeepCopy

func (in *SecretReference) DeepCopy() *SecretReference

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretReference.

func (*SecretReference) DeepCopyInto

func (in *SecretReference) DeepCopyInto(out *SecretReference)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type SecretRequirement

type SecretRequirement struct {
	// name of the Secret (must exist in the operator namespace).
	// Must be a valid RFC 1123 DNS subdomain.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	// +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="must be a valid DNS subdomain: lowercase alphanumeric characters, hyphens, and dots"
	Name string `json:"name,omitempty"`

	// description explains what this secret is used for, helping the
	// cluster admin understand what credentials to provide.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=1024
	Description string `json:"description,omitempty"`

	// mountAs specifies how the secret is exposed in the sandbox pod.
	// +required
	MountAs SecretMountSpec `json:"mountAs,omitzero"`
}

SecretRequirement declares a Kubernetes Secret that the sandbox needs at runtime. The Secret must exist in the operator namespace (where sandbox pods run), not in the Proposal's namespace.

func (*SecretRequirement) DeepCopy

func (in *SecretRequirement) DeepCopy() *SecretRequirement

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretRequirement.

func (*SecretRequirement) DeepCopyInto

func (in *SecretRequirement) DeepCopyInto(out *SecretRequirement)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type SkillsSource

type SkillsSource struct {
	// image is the OCI image reference containing skills.
	// The operator mounts this as a Kubernetes image volume (requires K8s 1.34+).
	// Must be a valid OCI image pullspec: a domain, followed by a repository path,
	// ending with either a tag (:tag) or a digest (@algorithm:hex).
	// Must be 1-512 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=512
	// +kubebuilder:validation:XValidation:rule="self.matches('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\\\b')",message="must start with a valid domain. valid domains must be alphanumeric characters (lowercase and uppercase) separated by the '.' character."
	// +kubebuilder:validation:XValidation:rule="self.find('(/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') != ”",message="a valid name is required. valid names must contain lowercase alphanumeric characters separated only by the '.', '_', '__', '-' characters."
	// +kubebuilder:validation:XValidation:rule="self.find('(@.*:)') != ” || self.find(':.*$') != ”",message="must end with a digest or a tag"
	// +kubebuilder:validation:XValidation:rule="self.find('(@.*:)') == ” ? (self.find(':.*$') != ” ? self.find(':.*$').substring(1).size() <= 127 : true) : true",message="tag must not be more than 127 characters"
	// +kubebuilder:validation:XValidation:rule="self.find('(@.*:)') == ” ? (self.find(':.*$') != ” ? self.find(':.*$').matches(':[\\\\w][\\\\w.-]*$') : true) : true",message="tag is invalid. valid tags must begin with a word character followed by word characters, '.', or '-'"
	// +kubebuilder:validation:XValidation:rule="self.find('(@.*:)') != ” ? self.find('(@.*:)').matches('(@[A-Za-z][A-Za-z0-9]*([_+.][A-Za-z][A-Za-z0-9]*)*[:])') : true",message="digest algorithm is not valid. valid algorithms must start with an alpha character followed by alphanumeric characters and may contain '-', '_', '+', and '.' characters."
	// +kubebuilder:validation:XValidation:rule="self.find('(@.*:)') != ” ? self.find(':.*$').substring(1).size() >= 32 : true",message="digest must be at least 32 characters"
	// +kubebuilder:validation:XValidation:rule="self.find('(@.*:)') != ” ? self.find(':.*$').matches(':[0-9A-Fa-f]*$') : true",message="digest must only contain hex characters (A-F, a-f, 0-9)"
	Image string `json:"image,omitempty"`

	// paths specifies which directories from the image are mounted.
	// Each path is mounted as a separate subPath volumeMount into the agent's
	// skills directory. The last segment of each path becomes the mount name
	// (e.g., "/skills/prometheus" mounts as "prometheus").
	//
	// Each path must be an absolute file path: starts with "/", no ".."
	// or "." segments, no double slashes, no trailing slash, and only
	// alphanumeric characters, hyphens, underscores, dots, and slashes.
	//
	// Maximum 50 items.
	// +required
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=50
	// +kubebuilder:validation:XValidation:rule="self.all(p, p.size() >= 2 && p.size() <= 512)",message="each path must be 2-512 characters"
	// +kubebuilder:validation:XValidation:rule="self.all(p, p.startsWith('/'))",message="each path must be absolute (start with '/')"
	// +kubebuilder:validation:XValidation:rule="self.all(p, !p.endsWith('/'))",message="paths must not end with '/'"
	// +kubebuilder:validation:XValidation:rule="self.all(p, !p.contains('//'))",message="paths must not contain double slashes"
	// +kubebuilder:validation:XValidation:rule="self.all(p, !p.contains('/../') && !p.endsWith('/..') && !p.contains('/./') && !p.endsWith('/.'))",message="paths must not contain '.' or '..' segments"
	// +kubebuilder:validation:XValidation:rule="self.all(p, p.matches('^[a-zA-Z0-9/_.-]+$'))",message="paths may only contain alphanumeric characters, '/', '_', '.', and '-'"
	// +kubebuilder:validation:items:MinLength=2
	// +kubebuilder:validation:items:MaxLength=512
	Paths []string `json:"paths"`
}

SkillsSource defines an OCI image containing skills and which paths within that image to mount. Skills are mounted as Kubernetes image volumes in the agent's sandbox pod.

Each path is mounted as a separate subPath volumeMount, allowing selective composition of skills from shared images.

Example — mount specific skills from the agentic-skills image:

skills:
  - image: registry.ci.openshift.org/ocp/5.0:agentic-skills
    paths:
      - /skills/cluster-update/update-advisor

func (*SkillsSource) DeepCopy

func (in *SkillsSource) DeepCopy() *SkillsSource

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SkillsSource.

func (*SkillsSource) DeepCopyInto

func (in *SkillsSource) DeepCopyInto(out *SkillsSource)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type StepPhase

type StepPhase string

StepPhase summarizes a single step's lifecycle state for display. Derived from per-step conditions via DeriveStepPhase; never stored on the CRD.

const (
	StepPhasePendingApproval StepPhase = "PendingApproval"
	StepPhaseRunning         StepPhase = "Running"
	StepPhaseCompleted       StepPhase = "Completed"
	StepPhaseFailed          StepPhase = "Failed"
	StepPhaseSkipped         StepPhase = "Skipped"
)

type StepResultRef

type StepResultRef struct {
	// name is the name of the result CR.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	Name string `json:"name,omitempty"`
	// outcome indicates the result of this step attempt.
	// Must be one of: Succeeded, Failed.
	// +required
	Outcome ActionOutcome `json:"outcome,omitempty"`
}

StepResultRef is a lightweight reference to a result CR with an inline success field for quick scanning without fetching the CR.

func (*StepResultRef) DeepCopy

func (in *StepResultRef) DeepCopy() *StepResultRef

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepResultRef.

func (*StepResultRef) DeepCopyInto

func (in *StepResultRef) DeepCopyInto(out *StepResultRef)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type StepsStatus

type StepsStatus struct {
	// analysis is the observed state of the analysis step.
	// +optional
	Analysis AnalysisStepStatus `json:"analysis,omitzero"`
	// execution is the observed state of the execution step.
	// +optional
	Execution ExecutionStepStatus `json:"execution,omitzero"`
	// verification is the observed state of the verification step.
	// +optional
	Verification VerificationStepStatus `json:"verification,omitzero"`
	// escalation is the observed state of the escalation step.
	// +optional
	Escalation EscalationStepStatus `json:"escalation,omitzero"`
}

StepsStatus contains the per-step observed state for all workflow steps. Each step status is populated independently as the proposal progresses through its lifecycle. All fields are set by the operator.

+kubebuilder:validation:MinProperties=1

func (*StepsStatus) DeepCopy

func (in *StepsStatus) DeepCopy() *StepsStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepsStatus.

func (*StepsStatus) DeepCopyInto

func (in *StepsStatus) DeepCopyInto(out *StepsStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ToolsSpec

type ToolsSpec struct {
	// skills defines one or more OCI images containing skills to mount
	// in the agent's sandbox pod. The operator creates Kubernetes image
	// volumes (requires K8s 1.34+) and mounts them into the agent's
	// skills directory. Each image must be unique within the list.
	// +optional
	// +listType=map
	// +listMapKey=image
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=20
	Skills []SkillsSource `json:"skills,omitempty"`

	// mcpServers defines external MCP (Model Context Protocol) servers the
	// agent can connect to for additional tools and context.
	// +optional
	// +listType=map
	// +listMapKey=name
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=20
	MCPServers []MCPServerConfig `json:"mcpServers,omitempty"`

	// requiredSecrets declares Kubernetes Secrets that the sandbox pod
	// needs at runtime. The cluster admin creates the actual Secrets
	// in the same namespace as the Proposal.
	// +optional
	// +listType=map
	// +listMapKey=name
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=20
	RequiredSecrets []SecretRequirement `json:"requiredSecrets,omitempty"`
}

ToolsSpec defines the tools available to an agent in its sandbox pod. This includes skills images, MCP servers, and required secrets.

ToolsSpec is specified on a Proposal either as a shared default (spec.tools) or per-step (spec.analysis.tools, spec.execution.tools, spec.verification.tools). Per-step tools replace the shared default for that step.

+kubebuilder:validation:MinProperties=1

func (*ToolsSpec) DeepCopy

func (in *ToolsSpec) DeepCopy() *ToolsSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ToolsSpec.

func (*ToolsSpec) DeepCopyInto

func (in *ToolsSpec) DeepCopyInto(out *ToolsSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (ToolsSpec) IsZero

func (t ToolsSpec) IsZero() bool

type VerificationApproval

type VerificationApproval struct {
	// agent is the Agent CR for this step. Defaults to "default".
	// +optional
	// +default="default"
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	// +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="must be a valid DNS subdomain: lowercase alphanumeric characters, hyphens, and dots"
	Agent string `json:"agent,omitempty"`
}

VerificationApproval contains approval parameters for the verification step.

+kubebuilder:validation:MinProperties=1

func (*VerificationApproval) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerificationApproval.

func (*VerificationApproval) DeepCopyInto

func (in *VerificationApproval) DeepCopyInto(out *VerificationApproval)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type VerificationPlan

type VerificationPlan struct {
	// description is a Markdown-formatted summary of the verification approach.
	// Maximum 4096 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=4096
	Description string `json:"description,omitempty"`
	// steps is the ordered list of verification checks to run.
	// Maximum 20 items.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=20
	Steps []VerificationStep `json:"steps,omitempty"`
}

VerificationPlan describes the complete verification strategy for a remediation. Populated by the analysis agent as part of a RemediationOption and used by the verification agent (if not skipped) to validate the remediation.

func (*VerificationPlan) DeepCopy

func (in *VerificationPlan) DeepCopy() *VerificationPlan

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerificationPlan.

func (*VerificationPlan) DeepCopyInto

func (in *VerificationPlan) DeepCopyInto(out *VerificationPlan)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type VerificationResult

type VerificationResult struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is the standard object metadata.
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty"`

	// spec contains the immutable identity fields for this result.
	// +required
	// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec is immutable"
	Spec VerificationResultSpec `json:"spec,omitzero"`

	// status contains result data and conditions.
	// +optional
	Status VerificationResultStatus `json:"status,omitzero"`
}

VerificationResult records the output of a single verification step execution. Created by the operator after the verification agent completes. Owned by the parent Proposal for garbage collection.

func (*VerificationResult) DeepCopy

func (in *VerificationResult) DeepCopy() *VerificationResult

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerificationResult.

func (*VerificationResult) DeepCopyInto

func (in *VerificationResult) DeepCopyInto(out *VerificationResult)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*VerificationResult) DeepCopyObject

func (in *VerificationResult) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*VerificationResult) GetConditions

func (r *VerificationResult) GetConditions() []metav1.Condition

func (*VerificationResult) SetConditions

func (r *VerificationResult) SetConditions(c []metav1.Condition)

type VerificationResultList

type VerificationResultList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []VerificationResult `json:"items"`
}

VerificationResultList contains a list of VerificationResult.

func (*VerificationResultList) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerificationResultList.

func (*VerificationResultList) DeepCopyInto

func (in *VerificationResultList) DeepCopyInto(out *VerificationResultList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*VerificationResultList) DeepCopyObject

func (in *VerificationResultList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type VerificationResultSpec

type VerificationResultSpec struct {
	// proposalName is the name of the parent Proposal in the same namespace.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	ProposalName string `json:"proposalName,omitempty"`

	// retryIndex is the 0-based retry index within the current analysis.
	// +required
	// +kubebuilder:validation:Minimum=0
	// +kubebuilder:validation:Maximum=2
	RetryIndex *int32 `json:"retryIndex,omitempty"`
}

VerificationResultSpec contains the immutable identity fields for a VerificationResult.

func (*VerificationResultSpec) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerificationResultSpec.

func (*VerificationResultSpec) DeepCopyInto

func (in *VerificationResultSpec) DeepCopyInto(out *VerificationResultSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type VerificationResultStatus

type VerificationResultStatus struct {
	// conditions track the lifecycle of this result.
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	// +optional
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=8
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`

	// checks contains individual verification check results.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=50
	Checks []VerifyCheck `json:"checks,omitempty"`

	// summary is a Markdown-formatted verification summary.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=32768
	Summary string `json:"summary,omitempty"`

	// sandbox tracks the sandbox pod used for this verification.
	// +optional
	Sandbox SandboxInfo `json:"sandbox,omitzero"`

	// failureReason is populated when the step failed due to a system error.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=8192
	FailureReason string `json:"failureReason,omitempty"`
}

VerificationResultStatus is the status of a VerificationResult.

+kubebuilder:validation:MinProperties=1

func (*VerificationResultStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerificationResultStatus.

func (*VerificationResultStatus) DeepCopyInto

func (in *VerificationResultStatus) DeepCopyInto(out *VerificationResultStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type VerificationStep

type VerificationStep struct {
	// name is a short identifier for this check (e.g., "pod-running").
	// Must be 1-253 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	Name string `json:"name,omitempty"`
	// command is the command or API call to run for this check
	// (e.g., "oc get pod -n production -l app=web -o jsonpath='{.items[0].status.phase}'").
	// Maximum 4096 characters.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=4096
	Command string `json:"command,omitempty"`
	// expected is the expected output or condition
	// (e.g., "Running", "ready=true"). Maximum 1024 characters.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=1024
	Expected string `json:"expected,omitempty"`
	// type categorizes the check (e.g., "command", "metric", "condition").
	// Must be 1-256 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=256
	Type string `json:"type,omitempty"`
}

VerificationStep describes a single verification check that the verification agent should run after execution. Populated by the analysis agent as part of the RemediationOption.

func (*VerificationStep) DeepCopy

func (in *VerificationStep) DeepCopy() *VerificationStep

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerificationStep.

func (*VerificationStep) DeepCopyInto

func (in *VerificationStep) DeepCopyInto(out *VerificationStep)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type VerificationStepStatus

type VerificationStepStatus struct {
	// conditions for this step.
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	// +optional
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=8
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
	// sandbox tracks the sandbox used.
	// +optional
	Sandbox SandboxInfo `json:"sandbox,omitzero"`
	// results references VerificationResult CRs, newest last.
	// Each entry corresponds to one verification attempt (including retries).
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=20
	Results []StepResultRef `json:"results,omitempty"`
}

VerificationStepStatus is the observed state of the verification step.

+kubebuilder:validation:MinProperties=1

func (*VerificationStepStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerificationStepStatus.

func (*VerificationStepStatus) DeepCopyInto

func (in *VerificationStepStatus) DeepCopyInto(out *VerificationStepStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type VerifyCheck

type VerifyCheck struct {
	// name is the check identifier, matching the VerificationStep name.
	// Maximum 253 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=253
	Name string `json:"name,omitempty"`
	// source is what performed the check (e.g., "oc", "promql", "curl").
	// Maximum 256 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=256
	Source string `json:"source,omitempty"`
	// value is the actual observed value (e.g., "Running", "3 replicas").
	// Maximum 4096 characters.
	// +required
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=4096
	Value string `json:"value,omitempty"`
	// result indicates whether the check's observed value matches
	// the expected value. Must be one of: Passed, Failed.
	// +required
	Result CheckResult `json:"result,omitempty"`
}

VerifyCheck is a single verification check result from the verification agent. Each check corresponds to a VerificationStep from the analysis agent's verification plan.

func (*VerifyCheck) DeepCopy

func (in *VerifyCheck) DeepCopy() *VerifyCheck

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerifyCheck.

func (*VerifyCheck) DeepCopyInto

func (in *VerifyCheck) DeepCopyInto(out *VerifyCheck)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL