Skip to content

chore(cli): Cleanup plan artifact.#3358

Closed
c-r33d wants to merge 1 commit intomainfrom
cleanup-plan-artifact
Closed

chore(cli): Cleanup plan artifact.#3358
c-r33d wants to merge 1 commit intomainfrom
cleanup-plan-artifact

Conversation

@c-r33d
Copy link
Copy Markdown
Contributor

@c-r33d c-r33d commented Apr 21, 2026

Summary

This PR simplifies the namespaced-policy migration plan so the emitted plan JSON is the primary output, rather than a richer artifact wrapper. It removes unused aggregate plan fields, collapses multi-target shapes where only a single target is valid, and trims bindings down to
the source identifiers execution actually needs.

No prune behavior is changed in this PR.

Changes

  • Removed top-level finalized-plan aggregates that are no longer needed:
    • unresolved
    • unused
  • Kept ActionPlan.references intact for provenance/debugging.
  • Simplified target shapes:
    • SubjectMappingPlan.targets[] -> target
    • RegisteredResourcePlan.targets[] -> target
    • ObligationTriggerPlan.targets[] -> target
  • Replaced nested existing objects with existing_id on finalized targets.
  • Simplified bindings to source IDs:
    • Subject mappings now use action_source_ids
    • Subject mappings now use subject_condition_set_source_id
    • Registered resource action bindings now keep source_action_id plus attribute_value
    • Obligation trigger targets now keep action_source_id
  • Renamed the Go field SubjectConditionSetSource to SubjectConditionSetSourceID while preserving the JSON key subject_condition_set_source_id.
  • Updated executor logic to consume the slimmer finalized plan shape.
  • Updated RR execution to resolve reused parent registered resources via existing_id.
  • Updated unit tests and BATS/JQ helpers to match the new plan contract.

Why

The previous plan shape carried review-oriented and duplicate data that execution did not need. This change makes the finalized plan smaller, clearer, and closer to the actual execution contract.

Testing

  • gofumpt -w on changed Go files
  • go test ./migrations/namespacedpolicy/...
  • golangci-lint run ./migrations/namespacedpolicy/...

Summary by CodeRabbit

  • New Features

    • Added support for enhanced registered resource lookups within migration plans.
  • Bug Fixes

    • Improved validation of unresolved resources during plan execution.
  • Refactor

    • Restructured plan data models to use singular target fields instead of collections.
    • Changed resource references to use identifiers instead of full object pointers for improved efficiency.
    • Simplified reference handling for actions, subject condition sets, and obligation triggers.

@c-r33d c-r33d requested a review from a team as a code owner April 21, 2026 18:04
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refactors the namespaced-policy migration plan to improve efficiency and clarity. By removing redundant data and simplifying the structure of the emitted plan JSON, the changes align the artifact more closely with the actual execution contract, resulting in a smaller and more maintainable plan format.

Highlights

  • Plan Schema Simplification: Simplified the namespaced-policy migration plan by removing unused aggregate fields and collapsing multi-target shapes into single targets where applicable.
  • Binding Optimization: Reduced binding complexity by replacing nested objects with source identifiers, streamlining the data required for execution.
  • Executor Logic Update: Updated executor logic to consume the new, slimmer plan shape and improved registered resource resolution using existing IDs.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.


The plan was heavy, filled with bloat, We trimmed the sails to help the boat. Now leaner, cleaner, swift and light, The migration runs with all its might.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 21, 2026

📝 Walkthrough

Walkthrough

This pull request refactors the namespaced-policy migration data model, replacing plural Targets slices and embedded policy objects with singular Target references and ID-based lookups. The schema changes convert Existing object pointers to ExistingID strings, simplify binding representations to source ID arrays, and update all corresponding execution, finalization, and test logic to match the new structure.

Changes

Cohort / File(s) Summary
Plan Data Model Schema
otdfctl/migrations/namespacedpolicy/plan.go
Removed Unused and Unresolved fields from Plan; replaced Existing object pointers with ExistingID strings across all target-plan types; converted plural Targets slices to singular Target for subject mapping, registered resource, and obligation trigger plans; replaced binding objects with source ID fields; updated TargetID() methods to use ExistingID; deleted binding/issue types (ActionBinding, SubjectConditionSetBinding, UnusedPlan, UnresolvedPlan).
Plan Finalization
otdfctl/migrations/namespacedpolicy/finalize_plan.go, otdfctl/migrations/namespacedpolicy/finalize_plan_test.go
Removed unused/unresolved tracking logic and associated helper methods; updated plan population from plural Targets lists to singular Target fields; replaced binding references with source ID fields (ActionSourceIDs, SubjectConditionSetSourceID, ActionSourceID); changed target plan storage from object references to ID-only (ExistingID); updated test assertions to match new target plan structure.
Subject Mapping Execution
otdfctl/migrations/namespacedpolicy/subject_mappings_execute.go, otdfctl/migrations/namespacedpolicy/subject_mappings_execute_test.go
Updated execution to process single Target instead of Targets slice; changed action/subject-condition-set resolution from binding objects to source ID arrays/strings; updated test data and assertions to use new ActionSourceIDs, SubjectConditionSetSourceID, and ExistingID fields.
Obligation Trigger Execution
otdfctl/migrations/namespacedpolicy/obligation_triggers_execute.go, otdfctl/migrations/namespacedpolicy/obligation_triggers_execute_test.go
Updated execution to iterate single Target instead of Targets slice; changed action reference from binding object to ActionSourceID string; refactored helper signature to accept source ID; updated test plan data model from plural to singular targets with source ID fields.
Registered Resource Execution
otdfctl/migrations/namespacedpolicy/registered_resources_execute.go, otdfctl/migrations/namespacedpolicy/registered_resources_execute_test.go
Updated execution to process single Target instead of slice; replaced target.Existing lookup with GetRegisteredResource call using ExistingID; added error handling for lookup failures; updated test fixtures and assertions to use new singular Target and ID-based fields.
Subject Condition Set & Action Execution
otdfctl/migrations/namespacedpolicy/subject_condition_sets_execute_test.go, otdfctl/migrations/namespacedpolicy/actions_execute_test.go
Updated test data to use ExistingID string fields instead of embedded policy objects for target plans; adjusted assertions to check ID-based fields instead of object references.
Executor Handler & Test Helpers
otdfctl/migrations/namespacedpolicy/execute.go, otdfctl/migrations/namespacedpolicy/execute_test_helpers_test.go
Added public method GetRegisteredResource(ctx, id, name, namespace) to ExecutorHandler interface; updated validation check to iterate registered resources instead of checking single Unresolved field; extended mock handler with registered resource lookup cache and implementation.
Planner Tests
otdfctl/migrations/namespacedpolicy/planner_test.go
Updated assertions to validate plan fields against revised data model: singular Target instead of Targets[0], ExistingID instead of embedded objects, source ID fields instead of binding objects.
E2E Tests
otdfctl/e2e/migrate-namespaced-policy.bats
Updated jq selectors to match new plan JSON shape: read targets via .target with null filtering, rename existing-id field lookup from .existing.id to .existing_id, adjust action/subject-condition-set status traversal to use source IDs and namespace placement.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~70 minutes

Possibly related PRs

Suggested labels

comp:policy, size/l

Suggested reviewers

  • elizabethhealy
  • alkalescent
  • jakedoublev

Poem

🐰 Targets once were plural, now they stand alone,
ExistingID replaces objects made of stone,
From binding webs to source IDs we've spun,
The migration model's shape has come undone! ✨
One target rules them all—refactored, clean, and bright. 🌟

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'chore(cli): Cleanup plan artifact' is vague and uses generic terminology that doesn't convey the specific refactoring being performed. Consider a more descriptive title such as 'refactor(migrations): Simplify namespaced-policy finalized plan structure' or 'chore(migrations): Consolidate plan targets and replace existing objects with IDs' to better reflect the substantial data model changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cleanup-plan-artifact

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

❤️ Share

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

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the migration planning and execution logic for namespaced policies by simplifying the Plan structure. Key changes include replacing Targets slices with a single Target for subject mappings, registered resources, and obligation triggers, and substituting complex object bindings with string IDs. The Unused and Unresolved sections were removed, and the ExecutorHandler interface now includes a GetRegisteredResource method. Feedback indicates that the validation logic for registered resources should be encapsulated within a Validate method on the Plan struct for better maintainability.

Comment on lines +97 to 101
for _, resource := range plan.RegisteredResources { // ? This should be a function withint the plan.go file
if resource != nil && resource.Unresolved != "" {
return fmt.Errorf("%w: finalized plan contains unresolved registered resources", ErrPlanNotExecutable)
}
}
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.

medium

As your comment on line 97 suggests, this validation logic would be better encapsulated as a method on the Plan struct. This improves maintainability by keeping the validation logic coupled with the data structure it validates.

Consider adding a Validate() method to the Plan struct in plan.go:

// In plan.go
func (p *Plan) Validate() error {
	for _, resource := range p.RegisteredResources {
		if resource != nil && resource.Unresolved != "" {
			return fmt.Errorf("%w: finalized plan contains unresolved registered resources", ErrPlanNotExecutable)
		}
	}
	return nil
}

Then, you can replace this loop with a call to plan.Validate().

@github-actions
Copy link
Copy Markdown
Contributor

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 135.800671ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 70.820255ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 341.086436ms
Throughput 293.18 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 34.009562796s
Average Latency 338.848717ms
Throughput 147.02 requests/second

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
otdfctl/migrations/namespacedpolicy/registered_resources_execute.go (1)

61-89: 🧹 Nitpick | 🔵 Trivial

Minor: redundant var err error shadow on line 70.

The outer err from line 61 is guaranteed nil after the if err != nil return at lines 62-68, so the inner var err error on line 70 is an unnecessary shadow. A plain = reuse would be clearer and avoid a potential govet/shadow finding.

♻️ Proposed simplification
 	if !hasExistingParent {
-		var err error
 		created, err = e.handler.CreateRegisteredResource(
 			ctx,
 			namespace,
 			plan.Source.GetName(),
 			nil,
 			metadataForCreate(
 				plan.Source.GetId(),
 				metadataLabels(plan.Source.GetMetadata()),
 				e.runID,
 			),
 		)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@otdfctl/migrations/namespacedpolicy/registered_resources_execute.go` around
lines 61 - 89, The inner shadowing of err is unnecessary: in
existingRegisteredResource call you already handled non-nil err, so in the block
that calls e.handler.CreateRegisteredResource (function
CreateRegisteredResource) remove the `var err error` declaration and reuse the
outer `err` by assigning with `=` when calling CreateRegisteredResource (i.e.,
`created, err = e.handler.CreateRegisteredResource(...)`) so there is no
shadowed variable and subsequent error handling that sets target.Execution and
returns uses the same err and runID.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@otdfctl/migrations/namespacedpolicy/execute.go`:
- Around line 97-101: The current check only scans RegisteredResources for
Unresolved but you must preflight all finalized targets before mutating; add a
helper function planHasUnresolvedTargets(plan *Plan) that iterates and returns
true if any target has status TargetStatusUnresolved across ActionPlan.Targets,
SubjectConditionSetPlan.Targets, SubjectMappingPlan.Target,
RegisteredResourcePlan.Unresolved and RegisteredResourcePlan.Target, and
ObligationTriggerPlan.Target; call this from validatePlan (or where you
currently check RegisteredResources in execute.go) and return fmt.Errorf("%w:
finalized plan contains unresolved targets", ErrPlanNotExecutable) if it finds
any unresolved so execution fails before any phase mutates state.

In `@otdfctl/migrations/namespacedpolicy/registered_resources_execute.go`:
- Around line 136-146: The helper existingRegisteredResource currently returns
(nil, true, err) when GetRegisteredResource fails, which makes the "has
existing" boolean ambiguous on error; change the return on error to (nil, false,
err) so that when e.handler.GetRegisteredResource(ctx, target.ExistingID, "",
"") fails the function returns false for the existence flag (and the error)
while keeping the normal successful-return semantics for
(*policy.RegisteredResource, true, nil).

---

Outside diff comments:
In `@otdfctl/migrations/namespacedpolicy/registered_resources_execute.go`:
- Around line 61-89: The inner shadowing of err is unnecessary: in
existingRegisteredResource call you already handled non-nil err, so in the block
that calls e.handler.CreateRegisteredResource (function
CreateRegisteredResource) remove the `var err error` declaration and reuse the
outer `err` by assigning with `=` when calling CreateRegisteredResource (i.e.,
`created, err = e.handler.CreateRegisteredResource(...)`) so there is no
shadowed variable and subsequent error handling that sets target.Execution and
returns uses the same err and runID.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 87662b4b-1272-4be9-8eae-e73f438ead65

📥 Commits

Reviewing files that changed from the base of the PR and between 95f2854 and 72d6658.

📒 Files selected for processing (15)
  • otdfctl/e2e/migrate-namespaced-policy.bats
  • otdfctl/migrations/namespacedpolicy/actions_execute_test.go
  • otdfctl/migrations/namespacedpolicy/execute.go
  • otdfctl/migrations/namespacedpolicy/execute_test_helpers_test.go
  • otdfctl/migrations/namespacedpolicy/finalize_plan.go
  • otdfctl/migrations/namespacedpolicy/finalize_plan_test.go
  • otdfctl/migrations/namespacedpolicy/obligation_triggers_execute.go
  • otdfctl/migrations/namespacedpolicy/obligation_triggers_execute_test.go
  • otdfctl/migrations/namespacedpolicy/plan.go
  • otdfctl/migrations/namespacedpolicy/planner_test.go
  • otdfctl/migrations/namespacedpolicy/registered_resources_execute.go
  • otdfctl/migrations/namespacedpolicy/registered_resources_execute_test.go
  • otdfctl/migrations/namespacedpolicy/subject_condition_sets_execute_test.go
  • otdfctl/migrations/namespacedpolicy/subject_mappings_execute.go
  • otdfctl/migrations/namespacedpolicy/subject_mappings_execute_test.go

Comment thread otdfctl/migrations/namespacedpolicy/execute.go
Comment on lines +136 to +146
func (e *Executor) existingRegisteredResource(ctx context.Context, target *RegisteredResourceTargetPlan) (*policy.RegisteredResource, bool, error) {
if target == nil || target.ExistingID == "" {
return nil, false, nil
}

resource, err := e.handler.GetRegisteredResource(ctx, target.ExistingID, "", "")
if err != nil {
return nil, true, err
}
return resource, true, nil
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Nit: returning hasExistingParent=true together with a non-nil error is ambiguous.

When GetRegisteredResource fails, the helper returns (nil, true, err). The current caller checks err first so this is harmless, but semantically "we have an existing parent" should be false when we failed to load it. Returning (nil, false, err) would make the contract safer against future caller refactors that might forget to check the error before branching on the bool.

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

In `@otdfctl/migrations/namespacedpolicy/registered_resources_execute.go` around
lines 136 - 146, The helper existingRegisteredResource currently returns (nil,
true, err) when GetRegisteredResource fails, which makes the "has existing"
boolean ambiguous on error; change the return on error to (nil, false, err) so
that when e.handler.GetRegisteredResource(ctx, target.ExistingID, "", "") fails
the function returns false for the existence flag (and the error) while keeping
the normal successful-return semantics for (*policy.RegisteredResource, true,
nil).

@github-actions
Copy link
Copy Markdown
Contributor

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • examples
  • otdfctl
  • sdk
  • service
  • lib/fixtures
  • tests-bdd

See the workflow run for details.

@c-r33d c-r33d closed this Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant