Skip to content

Conversation

@jsbroks
Copy link
Member

@jsbroks jsbroks commented May 1, 2025

Summary by CodeRabbit

  • New Features

    • Introduced AI-powered generation of policy names and descriptions.
    • Added the ability to evaluate deployment policies for specific environments and versions, providing detailed approval and selector results.
  • Refactor

    • Streamlined rule engine interfaces for policy evaluation, removing unnecessary context parameters for simpler and more consistent behavior.
  • Bug Fixes

    • Improved error handling for missing environments or versions during policy evaluation.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 1, 2025

Walkthrough

The changes introduce a new AI-powered router for generating policy names and descriptions, refactor the main policy API router to use a unified schema namespace, and add a nested router for evaluating environment-specific policy applicability to deployment versions. The environment policy evaluation logic fetches relevant policies, their rules, and checks both approval and version selector rules against a candidate version, returning detailed evaluation results. In the rule engine, method signatures are updated to remove the use of a context parameter, simplifying interfaces for rule evaluation, filtering, and pre-validation. Several functions and rules are made publicly exportable for broader use.

Changes

File(s) Change Summary
packages/api/src/router/policy.ts Refactored to add policyAiRouter for AI-based policy metadata generation; updated to use unified schema namespace; added environmentPolicy nested router for environment-version policy evaluation; introduced helper functions for selector and approval checks.
packages/rule-engine/src/manager/version-manager-rules.ts Changed versionAnyApprovalRule, versionRoleApprovalRule, and versionUserApprovalRule from private to exported constants.
packages/rule-engine/src/manager/version-manager.ts Removed unused imports; updated VersionReleaseManager.evaluate to call engine.evaluate without a context parameter.
packages/rule-engine/src/manager/version-rule-engine.ts Removed context parameter from evaluate and selectFinalRelease methods and corresponding internal calls, streamlining rule engine interfaces.
packages/rule-engine/src/rules/deployment-deny-rule.ts Removed context parameter from DeploymentDenyRule.passing method.
packages/rule-engine/src/rules/version-approval-rule.ts Removed context parameter from approval record functions and VersionApprovalRule.filter method; updated type signatures accordingly.
packages/rule-engine/src/types.ts Removed context parameter from FilterRule, PreValidationRule, and RuleEngine method signatures.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API
    participant AI
    participant DB

    Client->>API: Call policyAiRouter.generateName/Description(policyConfig)
    API->>AI: Send policy config to GPT-4 Turbo
    AI-->>API: Return generated name/description
    API-->>Client: Respond with generated metadata

    Client->>API: Call policyRouter.environmentPolicy.evaluateVersion(envId, versionId)
    API->>DB: Fetch environment, workspace, policies, policy rules, version
    API->>DB: Evaluate approval rules and version selectors
    API-->>Client: Return policies and evaluation results
Loading

Possibly related PRs

  • feat: version check ui #527: Adds UI and API for version selector checks, which directly relates to the new environment-version policy evaluation and selector logic.
  • add approval rule #454: Implements schema and rules for approval logic (versionUserApprovals, versionRoleApprovals, etc.), which are now integrated into the environment policy evaluation.

Poem

In the warren where policies grow,
AI helps their names to flow.
Approvals and selectors, all in a row,
Evaluated swiftly, results to show.
With context trimmed and exports anew,
The rule engine hops—more nimble too!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
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: 2

🔭 Outside diff range comments (1)
packages/rule-engine/src/rules/version-approval-rule.ts (1)

50-58: 🛠️ Refactor suggestion

No rejection reason when approvals are simply insufficient

Only explicit rejections generate a rejectionReasons entry.
When a version just lacks enough approvals (< minApprovals) it is silently filtered out, leaving the caller with no hint why.

-      return approvals.length >= this.options.minApprovals;
+      if (approvals.length < this.options.minApprovals) {
+        rejectionReasons.set(
+          release.id,
+          `Requires ≥${this.options.minApprovals} approvals; has ${approvals.length}.`,
+        );
+        return false;
+      }
+      return true;

Providing feedback avoids confusing “version disappeared” scenarios for users.

🧹 Nitpick comments (4)
packages/rule-engine/src/rules/version-approval-rule.ts (1)

36-43: Good refactor, but consider DB round-tripping

With the context argument removed, the method signature is cleaner.
However, each call to getApprovalRecords still performs one DB query per rule evaluation. If many policies share the same versions, you may issue the same query repeatedly. Caching by versionIds for the lifetime of the request (or batching queries) would cut latency.

packages/api/src/router/policy.ts (3)

37-97: Sanitisation is incomplete for AI-generated names

The post-processing only strips quotes/back-ticks.
Newlines and other control characters could still slip through and break UI rendering or logs.

-return text
-  .trim()
-  .replaceAll("`", "")
-  .replaceAll("'", "")
-  .replaceAll('"', "");
+return text
+  .trim()
+  .replace(/[`'"\n\r\t]/g, "");   // strip quotes and control chars

631-645: Inefficient existence check in getVersionSelector

Selecting full rows only to count them is wasteful.
Most SQL builders (including drizzle) expose an exists / select(1) helper that can short-circuit.

-return db
-  .select()
+return db
+  .select({ ok: 1 })

or use .count()/.exists() to avoid transferring data you never use.


658-676: Serial DB queries inside nested Promise loops

getApprovalReasons executes rule.filter() for every rule of every policy, each of which may hit the database.
For large policy sets this scales O(n·m) in round-trips.

Investigate:

  1. Let each rule implementation accept a shared cache object, or
  2. Aggregate versionIds per rule type and fetch approvals in one shot (similar to comment in VersionApprovalRule).

This will cut latency under heavy policy counts.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a28983 and df0e58b.

📒 Files selected for processing (7)
  • packages/api/src/router/policy.ts (15 hunks)
  • packages/rule-engine/src/manager/version-manager-rules.ts (3 hunks)
  • packages/rule-engine/src/manager/version-manager.ts (1 hunks)
  • packages/rule-engine/src/manager/version-rule-engine.ts (4 hunks)
  • packages/rule-engine/src/rules/deployment-deny-rule.ts (1 hunks)
  • packages/rule-engine/src/rules/version-approval-rule.ts (1 hunks)
  • packages/rule-engine/src/types.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{ts,tsx}`: **Note on Error Handling:** Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error...

**/*.{ts,tsx}: Note on Error Handling:
Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error handling. These are acceptable as long as they maintain clarity and predictability.

  • packages/rule-engine/src/types.ts
  • packages/rule-engine/src/rules/deployment-deny-rule.ts
  • packages/rule-engine/src/manager/version-rule-engine.ts
  • packages/rule-engine/src/manager/version-manager.ts
  • packages/rule-engine/src/manager/version-manager-rules.ts
  • packages/rule-engine/src/rules/version-approval-rule.ts
  • packages/api/src/router/policy.ts
🧬 Code Graph Analysis (3)
packages/rule-engine/src/rules/deployment-deny-rule.ts (1)
packages/rule-engine/src/types.ts (1)
  • PreValidationResult (45-48)
packages/rule-engine/src/manager/version-rule-engine.ts (1)
packages/rule-engine/src/types.ts (2)
  • RuleSelectionResult (87-90)
  • isPreValidationRule (67-71)
packages/rule-engine/src/rules/version-approval-rule.ts (2)
packages/rule-engine/src/manager/version-rule-engine.ts (1)
  • Version (12-18)
packages/rule-engine/src/types.ts (1)
  • RuleEngineRuleResult (30-33)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Typecheck
  • GitHub Check: Lint
  • GitHub Check: build (linux/amd64)
  • GitHub Check: build (linux/amd64)
🔇 Additional comments (7)
packages/rule-engine/src/rules/deployment-deny-rule.ts (1)

94-94: Signature simplification looks good

Removing the unused RuleEngineContext parameter from the passing() method simplifies the interface while maintaining the same functionality. This change aligns with the broader refactoring to remove context parameters from rule methods throughout the rule engine.

packages/rule-engine/src/manager/version-manager.ts (1)

192-192: API call updated correctly

The call to engine.evaluate() has been properly updated to remove the context parameter, consistent with the changes to the rule engine interfaces. The context is still properly retrieved from the database but is no longer passed to the evaluation method.

packages/rule-engine/src/types.ts (2)

52-52: Interface simplification is consistent

Removing the context parameter from the passing() method in the PreValidationRule interface properly aligns with the implementation changes seen in the rule classes. This simplification makes the API cleaner while maintaining functionality.


93-93: RuleEngine type updated correctly

The evaluate method signature in the RuleEngine type has been properly updated to remove the context parameter, ensuring type consistency throughout the rule engine system.

packages/rule-engine/src/manager/version-manager-rules.ts (1)

23-23: Making rule functions exportable improves modularity

Exporting the approval rule factory functions makes them available for external use, which improves the modularity of the system. This change enables these functions to be used in the new environment-specific policy evaluation logic while maintaining their current internal usage.

Also applies to: 35-35, 48-48

packages/rule-engine/src/manager/version-rule-engine.ts (1)

64-64: Validate all call-sites after the breaking API change

evaluate now only accepts candidates: Version[]. Please make sure every place in the codebase that previously called engine.evaluate(ctx, candidates) has been migrated; otherwise you will get silent undefined arguments or compile-time errors that break the deploy.
A quick rg "evaluate(" search should be enough.

packages/api/src/router/policy.ts (1)

510-539: Policy targeting logic ignores resource/deployment selectors

The applicablePolicyIds query explicitly filters for

isNull(policyTarget.resourceSelector),
isNull(policyTarget.deploymentSelector),

meaning policies that do define resource or deployment selectors are never evaluated, even if they might still match the current environment.
Is that intentional? If not, dropping those predicates (or adding the appropriate selector evaluation) will prevent accidental policy bypass.

Comment on lines +67 to 68
const result = rule.passing();

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Await the possibly-async passing() call

passing() used to accept a context argument and could legitimately be async (e.g. involve DB checks).
Removing the context did not guarantee it became synchronous, so calling it without await may turn result into a Promise, causing the subsequent property access (result.passing) to be undefined.

-const result = rule.passing();
+const result = await rule.passing();

If passing() is indeed synchronous, mark its return type as non-Promise so the compiler enforces this and prevents future misuse.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const result = rule.passing();
const result = await rule.passing();

Comment on lines +495 to +502
.query(async ({ ctx, input: { environmentId, versionId } }) => {
// First, find the environment and its associated workspace This is
// needed to scope the policy search to the correct workspace
const environment = await ctx.db.query.environment.findFirst({
where: eq(schema.environment.id, environmentId),
with: { system: { with: { workspace: true } } },
});
if (environment == null) throw new Error("Environment not found");
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Missing workspace / environment authorisation check

protectedProcedure guards the route, but there is no explicit check that the authenticated user can actually read the workspace linked to the environment.
If the caller knows an environmentId belonging to another workspace, this endpoint may leak policy metadata.

Consider adding:

authorizationCheck: ({ canUser, input }) =>
  canUser.perform(Permission.PolicyList).on({ type: "workspace", id: workspace.id }),

after the environment lookup.

@adityachoudhari26 adityachoudhari26 deleted the endpoint-for-checking-env-status branch May 7, 2025 06:41
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.

3 participants