Skip to content

feat(cli): Cleanup planner, handle unresolved RRs interactively.#3311

Merged
c-r33d merged 6 commits into
DSPX-2655-migrate-otdfctlfrom
interactive-resolution
Apr 20, 2026
Merged

feat(cli): Cleanup planner, handle unresolved RRs interactively.#3311
c-r33d merged 6 commits into
DSPX-2655-migrate-otdfctlfrom
interactive-resolution

Conversation

@c-r33d

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

Copy link
Copy Markdown
Contributor

Summary

This PR tightens the namespacedpolicy planner so registered resources are the only construct that can remain soft-unresolved during planning. All other policy constructs now fail fast when their target namespace or required dependencies cannot be derived.

It also cleans up resolver guard behavior so parent resolver functions own nil/source validation, while child helpers focus on namespace and existing-target resolution. For registered resources, unresolved state is now represented internally as a typed object
with a machine-checkable reason code plus a human-readable message.

In addition, we have merged in changes for interactively handling Registered Resources that are unresolved. RR Interactive

What Changed

  • Removed top-level Unresolved handling from actions, subject condition sets, subject mappings, and obligation triggers.
  • Kept registered resources as the only planner construct with soft unresolved behavior.
  • Added a typed RR unresolved model with:
    • Reason
    • Message
  • Preserved the existing artifact shape by continuing to emit the unresolved message as a string in the finalized plan.
  • Simplified action, subject condition set, and subject mapping resolver guard logic so invalid derived entries fail fast in the parent resolver.
  • Removed stale unresolved dependency/result handling from subject mapping dependency resolution.
  • Skipped registered resources with no AAVs during derivation and documented that behavior inline.

Why

The planner had accumulated multiple soft-unresolved paths that no longer matched the intended contract. This made the resolution flow harder to reason about and made tests rely on string matching for unresolved behavior.

This change makes the model stricter and simpler:

  • non-RR derivation/resolution failures are hard failures
  • RR namespace conflicts remain the only reviewable unresolved case
  • tests can now assert a typed unresolved reason instead of brittle strings

@c-r33d
c-r33d requested a review from a team as a code owner April 16, 2026 14:08
@coderabbitai

coderabbitai Bot commented Apr 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 90023448-b1ea-4071-b435-6c1fd3cc5c17

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch interactive-resolution

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.

@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 refines the namespacedpolicy planner to enhance its robustness and predictability. The core change involves shifting most policy constructs from a 'soft-unresolved' state to a 'fail-fast' model during planning, ensuring that issues with target namespace derivation or dependency resolution are immediately surfaced as errors. Registered Resources are an exception, retaining a soft-unresolved state but now with a more structured, typed representation. This makes the planning process more explicit and simplifies testing by allowing for assertion against specific error types rather than brittle string comparisons.

Highlights

  • Stricter Planner Behavior: The planner now enforces a stricter resolution model where non-Registered Resource (RR) policy constructs (Actions, Subject Condition Sets, Subject Mappings, Obligation Triggers) fail fast if their target namespace or required dependencies cannot be derived. Previously, these could remain 'soft-unresolved'.
  • Typed Unresolved State for Registered Resources: Registered Resources are now the only policy construct that can remain soft-unresolved. Their unresolved state is represented by a new typed object, Unresolved, which includes a machine-checkable Reason and a human-readable Message. This replaces the previous string-based Unresolved field.
  • Simplified Resolver Guard Logic: The resolver guard logic for Actions, Subject Condition Sets, and Subject Mappings has been simplified. Parent resolver functions now handle nil/source validation and fail fast on invalid derived entries, while child helpers focus on namespace and existing-target resolution.
  • Skipping Registered Resources without Action-Attribute Values: The derivation process now explicitly skips Registered Resources that do not have any Action-Attribute Values (AAVs), as they cannot provide a derivable namespace target.
  • Removed Stale Unresolved Handling: Stale unresolved dependency and result handling has been removed from Subject Mapping dependency resolution and various plan finalization steps, aligning with the new fail-fast approach for non-RR types.

🧠 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.


A planner's path, once soft and wide, Now narrows, errors can't abide. Except for resources, unique and grand, With reasons clear, across the land. Go's strictness guides, a cleaner hand.

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.

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

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.

Code Review

This pull request refactors the migration planning logic to handle resolution failures via error propagation instead of storing unresolved status strings in the plan structures. This change applies to Actions, Subject Condition Sets, Subject Mappings, and Obligation Triggers, while Registered Resources now use a structured Unresolved type for specific conflict cases. Feedback includes correcting a typo in a new error constant, improving error message context with namespace IDs, and removing a development comment.

Comment thread otdfctl/migrations/namespacedpolicy/plan.go Outdated
Comment thread otdfctl/migrations/namespacedpolicy/resolved.go Outdated
Comment thread otdfctl/migrations/namespacedpolicy/resolved.go Outdated
@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 179.493874ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 408.900314ms
Throughput 244.56 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 42.634052806s
Average Latency 423.492293ms
Throughput 117.28 requests/second

@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 189.65392ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 388.863751ms
Throughput 257.16 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.198852155s
Average Latency 400.092664ms
Throughput 124.38 requests/second

@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 185.840951ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 388.434123ms
Throughput 257.44 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.552421905s
Average Latency 402.742791ms
Throughput 123.30 requests/second

@c-r33d
c-r33d requested review from a team as code owners April 16, 2026 14:58
@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 144.462239ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 326.881752ms
Throughput 305.92 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 32.206627157s
Average Latency 320.663313ms
Throughput 155.25 requests/second

@c-r33d
c-r33d force-pushed the interactive-resolution branch from 402a472 to 16b705a Compare April 16, 2026 15:09
@github-actions

Copy link
Copy Markdown
Contributor

@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 191.03726ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 388.481634ms
Throughput 257.41 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.118363805s
Average Latency 399.307101ms
Throughput 124.63 requests/second

@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 147.163375ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 321.315819ms
Throughput 311.22 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 32.422787547s
Average Latency 322.735527ms
Throughput 154.21 requests/second

elizabethhealy
elizabethhealy previously approved these changes Apr 17, 2026
@alkalescent
alkalescent force-pushed the DSPX-2655-migrate-otdfctl branch from 73dba6c to 6475ea0 Compare April 20, 2026 17:47
@alkalescent
alkalescent requested a review from a team as a code owner April 20, 2026 17:47
## Summary

This PR adds planner-time interactive review for registered resources
that span multiple namespaces during namespaced policy migration.

  When --interactive is enabled, the planner now:

  - detects conflicting registered resources,
  - prompts the user to choose the target namespace,
  - filters the resource down to bindings for that namespace,
- updates any required action resolution so the final plan can proceed
cleanly.

  ## Prompt updates

  The interactive prompt was also cleaned up so that:

  - titles and descriptions render separately,
  - the registered resource identifier is shown in the title,
  - namespace options read clearly as migration choices.

  ## Scope

This change is intentionally limited to registered resource conflict
review only.

  It does not add:

  - broader planner summaries,
  - other interactive resolution flows,
  - non-RR interactive review behavior.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
* Interactive migration mode now available via `--interactive` flag.
When enabled, users are prompted to manually review and resolve
namespace conflicts for policy resources during migration. Users can
select the appropriate destination namespace for each affected resource,
with clear feedback on migration status.

* **Tests**
* Added comprehensive test coverage for interactive migration
functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@c-r33d
c-r33d force-pushed the interactive-resolution branch from 46251d0 to 78f6276 Compare April 20, 2026 21:18
@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 182.902685ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 419.033259ms
Throughput 238.64 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 42.52661531s
Average Latency 423.972319ms
Throughput 117.57 requests/second

@c-r33d c-r33d changed the title feat(cli): Cleanup planner feat(cli): Cleanup planner, handle unresolved RRs interactively. Apr 20, 2026
@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 requested a review from elizabethhealy April 20, 2026 21:25
@c-r33d
c-r33d merged commit d04286e into DSPX-2655-migrate-otdfctl Apr 20, 2026
37 checks passed
@c-r33d
c-r33d deleted the interactive-resolution branch April 20, 2026 21:34
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.

2 participants