Skip to content

feat: opa plan validations in workspace engine#1094

Merged
adityachoudhari26 merged 2 commits intomainfrom
init-validation
May 1, 2026
Merged

feat: opa plan validations in workspace engine#1094
adityachoudhari26 merged 2 commits intomainfrom
init-validation

Conversation

@adityachoudhari26
Copy link
Copy Markdown
Member

@adityachoudhari26 adityachoudhari26 commented May 1, 2026

fixes #1089

Summary by CodeRabbit

  • New Features
    • Plan validation using Open Policy Agent (OPA) policies is now supported. Users can define OPA validation rules within policy configurations to enforce custom deployment plan requirements. The system evaluates applicable rules for each deployment plan and produces detailed validation results, including pass/fail status, specific violation messages, and evaluation timestamps.

Copilot AI review requested due to automatic review settings May 1, 2026 13:27
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 1, 2026

Warning

Rate limit exceeded

@adityachoudhari26 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 22 minutes and 1 second before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 51c0729d-cc64-4cfb-8c12-175559cf119b

📥 Commits

Reviewing files that changed from the base of the PR and between 92ae764 and 17f7971.

📒 Files selected for processing (4)
  • apps/workspace-engine/svc/controllers/deploymentplanresult/controller.go
  • apps/workspace-engine/svc/controllers/deploymentplanresult/controller_test.go
  • apps/workspace-engine/svc/controllers/deploymentplanresult/validation.go
  • apps/workspace-engine/svc/controllers/deploymentplanresult/validation_test.go
📝 Walkthrough

Walkthrough

This PR introduces OPA-based plan validation to the deployment plan result workflow. It adds database tables to store validation rules and results, API schemas for rule/result types, database queries for data access, and controller logic to evaluate rules and persist outcomes.

Changes

Cohort / File(s) Summary
API Schema Definitions
apps/workspace-engine/oapi/openapi.json, apps/workspace-engine/oapi/spec/main.jsonnet, apps/workspace-engine/oapi/spec/schemas/plan_validation.jsonnet, apps/workspace-engine/oapi/spec/schemas/policy.jsonnet
Adds three new OpenAPI schemas (PlanValidationOpaRule, PlanValidationResult, PlanValidationViolation) and extends PolicyRule with optional planValidationOpa property.
OPA Generated Client
apps/workspace-engine/pkg/oapi/oapi.gen.go
Generates Go types for new plan validation schemas: PlanValidationOpaRule, PlanValidationResult, PlanValidationViolation, and updates PolicyRule struct with PlanValidationOpa field.
Database Schema & Configuration
apps/workspace-engine/pkg/db/queries/schema.sql, apps/workspace-engine/pkg/db/sqlc.yaml, apps/workspace-engine/pkg/db/models.go
Adds two new tables (policy_rule_plan_validation_opa for OPA rules, deployment_plan_target_result_validation for validation results), configures sqlc type overrides for violations column as []byte.
Database Query Layer
apps/workspace-engine/pkg/db/queries/plan_validation.sql, apps/workspace-engine/pkg/db/plan_validation.sql.go
Implements three SQLC queries: list workspace OPA rules, fetch current deployment version for plan target, and upsert validation results with conflict handling.
Controller Interfaces
apps/workspace-engine/svc/controllers/deploymentplanresult/getters.go, apps/workspace-engine/svc/controllers/deploymentplanresult/setters.go
Adds GetMatchingPlanValidationOpaRules and GetCurrentVersionForPlanTarget to Getter interface; adds UpsertPlanValidationResult to Setter interface.
Controller Implementation
apps/workspace-engine/svc/controllers/deploymentplanresult/getters_postgres.go, apps/workspace-engine/svc/controllers/deploymentplanresult/setters_postgres.go, apps/workspace-engine/svc/controllers/deploymentplanresult/validation.go
Implements getter/setter methods for PostgreSQL; adds RunPlanValidation function that fetches rules, constructs OPA input with plan/deployment/environment context, evaluates rules, and persists results.
Test Infrastructure
apps/workspace-engine/svc/controllers/deploymentplanresult/controller_test.go
Extends mock types to support plan validation rule retrieval, version lookup, and result upsert operations.

Sequence Diagram

sequenceDiagram
    actor Controller
    participant Getter
    participant DB
    participant OPA as OPA Engine
    participant Setter

    Controller->>Getter: GetMatchingPlanValidationOpaRules(workspaceID, target)
    Getter->>DB: Query policy_rule_plan_validation_opa rules
    DB-->>Getter: Return rule rows
    Getter->>Getter: Match selectors against target
    Getter-->>Controller: Return matching PolicyRules

    Controller->>Getter: GetCurrentVersionForPlanTarget(planTargetID)
    Getter->>DB: Query current deployment version
    DB-->>Getter: Return DeploymentVersion
    Getter-->>Controller: Return version

    Controller->>Controller: Construct OPA input (plan, version, context)

    loop For each matching rule
        Controller->>OPA: Evaluate rule.Rego with input
        OPA-->>Controller: Return violations (if any)
    end

    Controller->>Setter: UpsertPlanValidationResult(resultID, ruleID, passed, violations)
    Setter->>DB: INSERT/UPDATE deployment_plan_target_result_validation
    DB-->>Setter: Confirm upsert
    Setter-->>Controller: Return error status
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

  • #1091: The validation rows produced by this PR's upsert operations are intended to be read and rendered by the GitHub check logic in that issue.
  • #1073: This PR implements the OPA/Rego plan validation design, tables, and evaluation flow described in that parent issue.
  • #1088: Related schema definition PR that establishes the same plan-validation database table structure.

Possibly related PRs

  • #1092: Adds and configures the same plan-validation database tables and sqlc type mappings.
  • #733: Both PRs extend the PolicyRule schema with a new rule subtype (this PR adds planValidationOpa).
  • #813: Both PRs modify policy-related database models; the retrieved PR adds policy rule infrastructure, this one extends it with plan-validation-specific rules.

Suggested reviewers

  • jsbroks

Poem

🐰 A validation dance begins,
OPA rules spin and win,
Plans assessed with Rego's grace,
Results stored in their place,
Deployment wisdom runs so thin!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: opa plan validations in workspace engine' directly and concisely describes the main change: adding OPA-based plan validation functionality to the workspace engine.
Linked Issues check ✅ Passed The PR implementation fully meets the requirements from issue #1089: new validator.go with OPA rule loading and validation execution, OPA input construction with all required fields, upserting validation results to the database, and extending getters/setters with necessary queries.
Out of Scope Changes check ✅ Passed All changes are within scope of issue #1089: database schema/queries for plan validation, OpenAPI schema extensions for plan validation models, controller interface extensions, and implementation of the validator function—no unrelated functionality introduced.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch init-validation

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

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 22 minutes and 1 second.

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds the plumbing for OPA-based “plan validation” rules in workspace-engine, including new DB tables/queries and OpenAPI schemas, plus a controller-side validator implementation intended to run after a plan target result completes.

Changes:

  • Add policy_rule_plan_validation_opa and deployment_plan_target_result_validation tables + sqlc queries to load rules, fetch current version, and upsert validation results.
  • Extend deploymentplanresult Getter/Setter interfaces and Postgres implementations to support plan validation data access.
  • Add OpenAPI schema/types for plan validation rules and results.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
apps/workspace-engine/svc/controllers/deploymentplanresult/validation.go Implements rule matching, OPA input building, evaluation, and persistence.
apps/workspace-engine/svc/controllers/deploymentplanresult/getters.go Extends Getter interface for rule loading + current version lookup.
apps/workspace-engine/svc/controllers/deploymentplanresult/getters_postgres.go Implements Postgres getters for plan validation rule selection and current version lookup.
apps/workspace-engine/svc/controllers/deploymentplanresult/setters.go Extends Setter interface for validation upsert.
apps/workspace-engine/svc/controllers/deploymentplanresult/setters_postgres.go Implements Postgres upsert for validation results.
apps/workspace-engine/svc/controllers/deploymentplanresult/controller_test.go Updates mocks to satisfy new interfaces.
apps/workspace-engine/pkg/db/sqlc.yaml Registers new query file + type override for violations JSONB.
apps/workspace-engine/pkg/db/queries/schema.sql Adds schema definitions for plan validation rules/results tables.
apps/workspace-engine/pkg/db/queries/plan_validation.sql Adds sqlc queries for listing rules, reading current version, and upserting results.
apps/workspace-engine/pkg/db/plan_validation.sql.go Generated sqlc output for new queries.
apps/workspace-engine/pkg/db/models.go Adds generated model structs for new tables.
apps/workspace-engine/oapi/spec/schemas/policy.jsonnet Adds planValidationOpa rule type to PolicyRule schema.
apps/workspace-engine/oapi/spec/schemas/plan_validation.jsonnet Defines schemas for OPA plan validation rule + results.
apps/workspace-engine/oapi/spec/main.jsonnet Includes the new plan validation schema module.
apps/workspace-engine/pkg/oapi/oapi.gen.go Generated OpenAPI types for plan validation rule/result.
apps/workspace-engine/oapi/openapi.json Generated OpenAPI schema output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +17 to +24
func RunPlanValidation(
ctx context.Context,
getter Getter,
setter Setter,
result db.DeploymentPlanTargetResult,
planResult *types.PlanResult,
dispatchCtx oapi.DispatchContext,
) error {
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

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

RunPlanValidation is not referenced anywhere in the repo right now, so the new plan validation logic will never run (and the PR description says it should run after saving a completed plan result). Wire this into the deploymentplanresult controller’s completed path (after UpdateDeploymentPlanTargetResultCompleted, before MaybeUpdateTargetCheck), or remove the unused implementation if it’s intentionally deferred.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +38
func RunPlanValidation(
ctx context.Context,
getter Getter,
setter Setter,
result db.DeploymentPlanTargetResult,
planResult *types.PlanResult,
dispatchCtx oapi.DispatchContext,
) error {
ctx, span := tracer.Start(ctx, "RunPlanValidation")
defer span.End()

span.SetAttributes(attribute.String("result_id", result.ID.String()))

target := &match.Target{
Deployment: dispatchCtx.Deployment,
Environment: dispatchCtx.Environment,
Resource: dispatchCtx.Resource,
}

workspaceID, err := uuid.Parse(dispatchCtx.Environment.WorkspaceId)
if err != nil {
return fmt.Errorf("parse workspace id: %w", err)
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

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

RunPlanValidation dereferences dispatchCtx.Environment and planResult without nil checks (e.g., dispatchCtx.Environment.WorkspaceId, planResult.Current). Since both are pointers in the input types, this can panic if the caller passes an incomplete dispatch context or a nil plan result. Consider changing the signature to take a non-pointer plan result and explicitly validating required dispatch context fields up front (returning an error) to avoid panics.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +75
func RunPlanValidation(
ctx context.Context,
getter Getter,
setter Setter,
result db.DeploymentPlanTargetResult,
planResult *types.PlanResult,
dispatchCtx oapi.DispatchContext,
) error {
ctx, span := tracer.Start(ctx, "RunPlanValidation")
defer span.End()

span.SetAttributes(attribute.String("result_id", result.ID.String()))

target := &match.Target{
Deployment: dispatchCtx.Deployment,
Environment: dispatchCtx.Environment,
Resource: dispatchCtx.Resource,
}

workspaceID, err := uuid.Parse(dispatchCtx.Environment.WorkspaceId)
if err != nil {
return fmt.Errorf("parse workspace id: %w", err)
}

rules, err := getter.GetMatchingPlanValidationOpaRules(ctx, workspaceID, target)
if err != nil {
return fmt.Errorf("get matching opa rules: %w", err)
}

span.SetAttributes(attribute.Int("rules.count", len(rules)))

if len(rules) == 0 {
return nil
}

input, err := buildOpaInput(ctx, getter, result.TargetID, planResult, dispatchCtx)
if err != nil {
return fmt.Errorf("build opa input: %w", err)
}

results, err := evaluateRules(ctx, rules, input)
if err != nil {
return fmt.Errorf("evaluate rules: %w", err)
}

span.SetAttributes(attribute.Int("rules.evaluated", len(results)))

for _, rule := range rules {
res, ok := results[rule.Id]
if !ok {
continue
}
if err := persistResult(ctx, setter, result.ID, rule, res); err != nil {
return fmt.Errorf("persist result for rule %s: %w", rule.Id, err)
}
}

return nil
}
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

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

This PR introduces substantial new behavior (rule loading, OPA input construction, rule evaluation, DB upsert) but there are no unit tests covering it. Add tests that verify: matching rules are selected by selector, OPA evaluation results are interpreted correctly (pass/deny messages), and UpsertPlanValidationResult is called with the expected passed/violations payloads.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/workspace-engine/svc/controllers/deploymentplanresult/controller_test.go (2)

128-133: ⚡ Quick win

Capture validation upsert calls and allow injected errors in mock setter.

The current stub always succeeds and discards args, which prevents asserting invocation details and error propagation for the new validation write step.

Proposed test-harness improvement
 type mockSetter struct {
 	completedCalls []completedCall
 	completedErr   error

 	stateCalls []stateCall
 	stateErr   error
+
+	validationUpserts []db.UpsertPlanValidationResultParams
+	validationErr     error
 }
@@
 func (m *mockSetter) UpsertPlanValidationResult(
 	_ context.Context,
-	_ db.UpsertPlanValidationResultParams,
+	arg db.UpsertPlanValidationResultParams,
 ) error {
-	return nil
+	m.validationUpserts = append(m.validationUpserts, arg)
+	return m.validationErr
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/workspace-engine/svc/controllers/deploymentplanresult/controller_test.go`
around lines 128 - 133, The mock UpsertPlanValidationResult currently swallows
its inputs and always returns nil; modify the mockSetter struct to include
fields for capturing the last context and last params (e.g., lastUpsertCtx,
lastUpsertParams) and an injectable error field (e.g., upsertErr), then update
mockSetter.UpsertPlanValidationResult to store the incoming context and
db.UpsertPlanValidationResultParams into those fields and return the injectable
upsertErr so tests can assert the call parameters and simulate errors.

71-84: ⚡ Quick win

Expose configurable returns in new getter stubs to enable validation-path tests.

Right now these methods are hardcoded to nil, nil, so tests can’t meaningfully cover matched-rule/current-version branches for the new validation flow.

Proposed test-harness improvement
 type mockGetter struct {
 	result db.DeploymentPlanTargetResult
 	err    error
+	planValidationRules []oapi.PolicyRule
+	planValidationErr   error
+	currentVersion      *oapi.DeploymentVersion
+	currentVersionErr   error
 }
@@
 func (m *mockGetter) GetMatchingPlanValidationOpaRules(
 	_ context.Context,
 	_ uuid.UUID,
 	_ *match.Target,
 ) ([]oapi.PolicyRule, error) {
-	return nil, nil
+	return m.planValidationRules, m.planValidationErr
 }
@@
 func (m *mockGetter) GetCurrentVersionForPlanTarget(
 	_ context.Context,
 	_ uuid.UUID,
 ) (*oapi.DeploymentVersion, error) {
-	return nil, nil
+	return m.currentVersion, m.currentVersionErr
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/workspace-engine/svc/controllers/deploymentplanresult/controller_test.go`
around lines 71 - 84, The two mock methods GetMatchingPlanValidationOpaRules and
GetCurrentVersionForPlanTarget currently always return nil, nil which prevents
exercising validation branches; modify the mockGetter type to include
configurable fields (e.g., MatchingRulesReturn []oapi.PolicyRule and
MatchingRulesErr error, and CurrentVersionReturn *oapi.DeploymentVersion and
CurrentVersionErr error), then update GetMatchingPlanValidationOpaRules to
return m.MatchingRulesReturn, m.MatchingRulesErr and
GetCurrentVersionForPlanTarget to return m.CurrentVersionReturn,
m.CurrentVersionErr so tests can inject different rule lists and version
values/errors for validation-path test cases.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/workspace-engine/svc/controllers/deploymentplanresult/validation.go`:
- Around line 30-39: The code dereferences dispatchCtx.Environment and
planResult without nil checks (e.g., when constructing match.Target and parsing
dispatchCtx.Environment.WorkspaceId), which can panic; update the validation
logic in validation.go to guard against nil dispatchCtx.Environment and nil
planResult before accessing their fields, returning a retriable error (with
clear context) when either is missing, and only call uuid.Parse on a non-empty
dispatchCtx.Environment.WorkspaceId; reference the match.Target construction,
the workspaceID parsing block, and any later uses of planResult to add these nil
checks and early returns.

---

Nitpick comments:
In
`@apps/workspace-engine/svc/controllers/deploymentplanresult/controller_test.go`:
- Around line 128-133: The mock UpsertPlanValidationResult currently swallows
its inputs and always returns nil; modify the mockSetter struct to include
fields for capturing the last context and last params (e.g., lastUpsertCtx,
lastUpsertParams) and an injectable error field (e.g., upsertErr), then update
mockSetter.UpsertPlanValidationResult to store the incoming context and
db.UpsertPlanValidationResultParams into those fields and return the injectable
upsertErr so tests can assert the call parameters and simulate errors.
- Around line 71-84: The two mock methods GetMatchingPlanValidationOpaRules and
GetCurrentVersionForPlanTarget currently always return nil, nil which prevents
exercising validation branches; modify the mockGetter type to include
configurable fields (e.g., MatchingRulesReturn []oapi.PolicyRule and
MatchingRulesErr error, and CurrentVersionReturn *oapi.DeploymentVersion and
CurrentVersionErr error), then update GetMatchingPlanValidationOpaRules to
return m.MatchingRulesReturn, m.MatchingRulesErr and
GetCurrentVersionForPlanTarget to return m.CurrentVersionReturn,
m.CurrentVersionErr so tests can inject different rule lists and version
values/errors for validation-path test cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 22391fdb-d357-4a1a-9022-e9e9fd615564

📥 Commits

Reviewing files that changed from the base of the PR and between 4957142 and 92ae764.

📒 Files selected for processing (16)
  • apps/workspace-engine/oapi/openapi.json
  • apps/workspace-engine/oapi/spec/main.jsonnet
  • apps/workspace-engine/oapi/spec/schemas/plan_validation.jsonnet
  • apps/workspace-engine/oapi/spec/schemas/policy.jsonnet
  • apps/workspace-engine/pkg/db/models.go
  • apps/workspace-engine/pkg/db/plan_validation.sql.go
  • apps/workspace-engine/pkg/db/queries/plan_validation.sql
  • apps/workspace-engine/pkg/db/queries/schema.sql
  • apps/workspace-engine/pkg/db/sqlc.yaml
  • apps/workspace-engine/pkg/oapi/oapi.gen.go
  • apps/workspace-engine/svc/controllers/deploymentplanresult/controller_test.go
  • apps/workspace-engine/svc/controllers/deploymentplanresult/getters.go
  • apps/workspace-engine/svc/controllers/deploymentplanresult/getters_postgres.go
  • apps/workspace-engine/svc/controllers/deploymentplanresult/setters.go
  • apps/workspace-engine/svc/controllers/deploymentplanresult/setters_postgres.go
  • apps/workspace-engine/svc/controllers/deploymentplanresult/validation.go

Comment on lines +30 to +39
target := &match.Target{
Deployment: dispatchCtx.Deployment,
Environment: dispatchCtx.Environment,
Resource: dispatchCtx.Resource,
}

workspaceID, err := uuid.Parse(dispatchCtx.Environment.WorkspaceId)
if err != nil {
return fmt.Errorf("parse workspace id: %w", err)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Prevent nil-pointer panics in validation path.

Line 36 and Line 90+ dereference pointer fields (dispatchCtx.Environment, planResult) without guards. If either is absent in stored dispatch context/plan payload, this panics the controller instead of returning a retriable error.

Suggested fix
 func RunPlanValidation(
 	ctx context.Context,
 	getter Getter,
 	setter Setter,
 	result db.DeploymentPlanTargetResult,
 	planResult *types.PlanResult,
 	dispatchCtx oapi.DispatchContext,
 ) error {
 	ctx, span := tracer.Start(ctx, "RunPlanValidation")
 	defer span.End()

+	if planResult == nil {
+		return fmt.Errorf("missing plan result")
+	}
+	if dispatchCtx.Environment == nil {
+		return fmt.Errorf("missing environment in dispatch context")
+	}
+
 	span.SetAttributes(attribute.String("result_id", result.ID.String()))
@@
-	workspaceID, err := uuid.Parse(dispatchCtx.Environment.WorkspaceId)
+	workspaceID, err := uuid.Parse(dispatchCtx.Environment.WorkspaceId)

Also applies to: 89-93

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/workspace-engine/svc/controllers/deploymentplanresult/validation.go`
around lines 30 - 39, The code dereferences dispatchCtx.Environment and
planResult without nil checks (e.g., when constructing match.Target and parsing
dispatchCtx.Environment.WorkspaceId), which can panic; update the validation
logic in validation.go to guard against nil dispatchCtx.Environment and nil
planResult before accessing their fields, returning a retriable error (with
clear context) when either is missing, and only call uuid.Parse on a non-empty
dispatchCtx.Environment.WorkspaceId; reference the match.Target construction,
the workspaceID parsing block, and any later uses of planResult to add these nil
checks and early returns.

@adityachoudhari26 adityachoudhari26 merged commit 92c4212 into main May 1, 2026
8 of 10 checks passed
@adityachoudhari26 adityachoudhari26 deleted the init-validation branch May 1, 2026 14:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: plan validation step in deploymentplanresult controller

2 participants