Guard Rails: Rename & Expand Code Reviews

publicv1
5h ago
8 views5 comments1 reviews11 min read

The existing "Code Review" feature provides AI-powered code analysis before deployments. It's fully implemented but triple-gated behind beta_features?, closed_beta_code_reviews_allowed?, and ai_code_review_allowed? -- no customer has ever seen it. We're rebranding it to "Guard Rails" and expanding it from a single AI check into a configurable pre-deployment safety layer with multiple check types.

Since no customer has used the feature, we can freely rename tables, models, routes, and UI without backwards compatibility concerns.

  • MVP Scope: Phase 1 (rename) + Phase 2 (rules engine + branch restriction) delivered together
  • Feature Gating: Keep existing triple gate (beta_features? + closed_beta_guard_rails_allowed? + guard_rails_allowed?). Only gradually open up.
  • Package Config: Rename keys to guard_rails_* for clean break
  • Opt-in / Manual: Guard Rails are NOT automatic. Users manually trigger them from the deployment form. They configure which checks are available, then opt-in per deployment.

#1. Project Sidebar Navigation

Guard Rails gets its own entry in the project sidebar, between "Automatic Deployments" and "Build Pipeline":

Deployments
Servers & Groups
Config Files
Environment Variables
Excluded Files
Integrations
SSH Commands
Automatic Deployments
► Guard Rails            ← NEW
Build Pipeline
Insights
Settings

#2. Guard Rails Settings Page (per project)

┌─────────────────────────────────────────────────────────────┐
│  Guard Rails                          [+ Add Guard Rail]    │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ℹ️ Guard Rails are pre-deployment checks you can run      │
│  before deploying. Configure the checks below, then        │
│  trigger them from the deployment form.                     │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 🔍 AI Code Review                    [Enabled] ✓    │   │
│  │ AI-powered analysis of your code changes for        │   │
│  │ security, performance, and quality issues.          │   │
│  │ Mode: Warn only                        [Edit]       │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 🌿 Branch Restriction                [Enabled] ✓    │   │
│  │ Only allow deployments from approved branches.      │   │
│  │ Allowed: main, release/*              [Edit]        │   │
│  │ Mode: Block deployment                              │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 🔒 Env Variable Check               [Disabled]      │   │
│  │ Verify required environment variables are set.      │   │
│  │                                        [Edit]       │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Each rule card shows:

  • Type icon + name
  • Brief description
  • Enable/disable toggle
  • Mode: "Block deployment" (blocking) or "Warn only" (non-blocking)
  • Configuration summary (e.g., which branches, which env vars)
  • Edit button -> opens edit form with type-specific fields

#3. Add Guard Rail Form

┌─────────────────────────────────────────────────────────────┐
│  New Guard Rail                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Type:  [AI Code Review      ▼]                             │
│         [Branch Restriction   ]                             │
│                                                             │
│  ── Branch Restriction Settings ──                          │
│                                                             │
│  Mode:   (•) Only allow these branches (allowlist)          │
│          ( ) Block these branches (blocklist)                │
│                                                             │
│  Branches:  [ main, release/*, hotfix/* ]                   │
│  (comma-separated, supports * wildcards)                    │
│                                                             │
│  If check fails:                                            │
│          (•) Block deployment                               │
│          ( ) Warn only (allow deployment to proceed)        │
│                                                             │
│           [Cancel]  [Save Guard Rail]                       │
└─────────────────────────────────────────────────────────────┘

#4. New Deployment Form (updated)

The existing "Code Review" section becomes "Guard Rails". It's shown when the project has at least one enabled guard rail rule:

┌─────────────────────────────────────────────────────────────┐
│  New Deployment                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Server:    [Production (main)    ▼]                        │
│  From:      [abc1234] ───────► To: [def5678]                │
│                                                             │
│  ── Guard Rails ──────────────────────────────────────────  │
│  │                                                       │  │
│  │  ✦ Run pre-deployment checks on your code changes     │  │
│  │  2 checks configured · 47 checks remaining today      │  │
│  │                                                       │  │
│  │  [  ✦ Run Guard Rails  ]   [ Deploy ▶ ]               │  │
│  │                                                       │  │
│  └───────────────────────────────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘
  • "Run Guard Rails" button triggers checks, redirects to results page
  • "Deploy" button deploys directly (skipping guard rails -- it's opt-in)
  • When no guard rail rules are configured, this section is hidden

#5. Guard Rails Results Page

After clicking "Run Guard Rails", the user sees results for ALL configured checks:

┌─────────────────────────────────────────────────────────────┐
│  Guard Rails Results                                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌── Check Results ───────────────────────────────────┐    │
│  │                                                     │    │
│  │  ✅ Branch Restriction                   PASSED     │    │
│  │     Deploying from 'main' — branch is allowed       │    │
│  │                                                     │    │
│  │  🔄 AI Code Review                    ANALYZING...  │    │
│  │     ████████░░░░░░░░ 55%                            │    │
│  │     Analyzing code changes...                       │    │
│  │                                                     │    │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Waiting for all checks to complete...                      │
│                                                             │
│  [Back to Deployment]                                       │
└─────────────────────────────────────────────────────────────┘

Once all checks complete:

┌─────────────────────────────────────────────────────────────┐
│  Guard Rails Results                                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌── Check Results ───────────────────────────────────┐    │
│  │                                                     │    │
│  │  ✅ Branch Restriction                   PASSED     │    │
│  │     Deploying from 'main' — branch is allowed       │    │
│  │                                                     │    │
│  │  ⚠️  AI Code Review          Score: 72 / 100       │    │
│  │     2 high severity findings, 3 medium              │    │
│  │     [View Full Report ▶]                            │    │
│  │                                                     │    │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ⚠️ Guard Rails passed with warnings.                      │
│  Review the findings before deploying.                      │
│                                                             │
│  [Back to Deployment]            [Run Deployment ▶]         │
└─────────────────────────────────────────────────────────────┘

If a blocking check fails:

│  ❌ Branch Restriction                     BLOCKED     │
│     Branch 'feature/experiment' is not allowed.        │
│     Allowed branches: main, release/*                  │
│                                                        │
│  ❌ Deployment blocked by Guard Rails.                 │
│  Fix the issues above before deploying.                │
│                                                        │
│  [Back to Deployment]                                  │

#6. User Flow Summary

Configure (once)                    Deploy (each time)
─────────────────                   ──────────────────
Project Sidebar                     New Deployment Form
  └─► Guard Rails Settings            ├─► [Run Guard Rails] (opt-in)
       ├─► Add rules                  │     └─► Results page
       ├─► Enable/disable             │          ├─► All pass → [Run Deployment]
       ├─► Set blocking/warn          │          ├─► Warn → [Run Deployment] (proceed anyway)
       └─► Configure per type         │          └─► Blocked → must fix first
                                      └─► [Deploy] (skip guard rails entirely)

Mechanical rename across the entire codebase. The AI code review becomes one "type" of guard rail check.

#1.1 Database Migration

New file: db/migrate/TIMESTAMP_rename_code_reviews_to_guard_rail_checks.rb

  • rename_table :code_reviews, :guard_rail_checks
  • add_column :guard_rail_checks, :check_type, :string, default: 'ai_code_review', null: false, after: :id
  • add_index :guard_rail_checks, :check_type, length: 191
  • rename_table :code_review_usages, :guard_rail_check_usages
  • rename_column :guard_rail_check_usages, :code_review_id, :guard_rail_check_id

Safe to use rename_table -- these are NOT in the Lhm-required large tables list.

#1.2 Model Renames

OldNewNotes
app/models/code_review.rbapp/models/guard_rail_check.rbClass GuardRailCheck, add check_type validation, rename has_one :code_review_usage -> has_one :guard_rail_check_usage
app/models/code_review_usage.rbapp/models/guard_rail_check_usage.rbClass GuardRailCheckUsage, rename belongs_to :code_review -> belongs_to :guard_rail_check

#1.3 Controller Rename

OldNew
app/controllers/deployments/code_review_controller.rbapp/controllers/deployments/guard_rails_controller.rb

Class: Deployments::GuardRailsController. Update all internal references.

#1.4 Job Rename

OldNew
app/jobs/generate_code_review_job.rbapp/jobs/generate_guard_rail_check_job.rb

Class: GenerateGuardRailCheckJob. Keep Ai::CodeReviewService name (it's specific to AI reviews, correct as-is).

#1.5 Routes

# config/routes.rb - replace lines 168-170
get :guard_rails, to: 'deployments/guard_rails#index', on: :member
delete :guard_rails, to: 'deployments/guard_rails#destroy', on: :member
post 'guard_rails/feedback', to: 'deployments/guard_rails#feedback', on: :member

#1.6 Account Model (app/models/account.rb)

Rename 6 methods:

  • code_review_allowed? -> guard_rails_allowed?
  • closed_beta_code_reviews_allowed? -> closed_beta_guard_rails_allowed?
  • daily_code_review_limit -> daily_guard_rail_limit
  • code_review_daily_limit_reached? -> guard_rail_daily_limit_reached?
  • code_reviews_today_count -> guard_rail_checks_today_count
  • code_reviews_remaining_today -> guard_rail_checks_remaining_today

#1.7 Deployment Model (app/models/deployment.rb)

  • has_many :code_reviews -> has_many :guard_rail_checks
  • can_request_code_review? -> can_request_guard_rail_check?
  • latest_code_review -> latest_guard_rail_check
  • code_review_count -> guard_rail_check_count
  • remaining_code_reviews -> remaining_guard_rail_checks

#1.8 CreateController (app/controllers/deployments/create_controller.rb)

  • code_review? -> guard_rails? (check params[:deployment][:mode] == 'guard_rails')
  • code_review_eligible? -> guard_rails_eligible?
  • handle_ineligible_code_review -> handle_ineligible_guard_rails
  • Redirect path: code_review_project_deployment_path -> guard_rails_project_deployment_path
  • Activity key: deployment_code_review_started -> deployment_guard_rails_started

#1.9 Presenter (app/presenters/deployment_component_presenter.rb)

  • code_reviews -> guard_rail_checks (hash key + method)
  • code_review_enabled? -> guard_rails_enabled?
  • can_request_code_review? -> can_request_guard_rail_check?

#1.10 View

  • app/views/deployments/code_review/ -> app/views/deployments/guard_rails/
  • Update title text: "AI Code Review" -> "Guard Rails"

#1.11 React Components

OldNew
CodeReviewReport.jsxGuardRailReport.jsx
CodeReviewLoader.jsxGuardRailLoader.jsx
CodeReviewScore.jsxGuardRailScore.jsx
CodeReviewFinding.jsxGuardRailFinding.jsx

Update component registration names (DeployHQ.components.CodeReviewReport -> DeployHQ.components.GuardRailReport), user-facing text, and prop names.

In NewDeploymentForm.jsx: change mode value code_review -> guard_rails, button text -> "Run Guard Rails", update descriptions.

#1.12 SCSS Files

OldNew
atoms/_code-review-score.scssatoms/_guard-rail-score.scss
molecules/_code-review-finding.scssmolecules/_guard-rail-finding.scss
organisms/_code-review-report.scssorganisms/_guard-rail-report.scss
organisms/_code-review-loader.scssorganisms/_guard-rail-loader.scss

Rename all CSS classes: .o-code-review-* -> .o-guard-rail-*, .m-code-review-* -> .m-guard-rail-*, .a-code-review-* -> .a-guard-rail-*

Update SCSS index files that import these partials.

#1.13 Specs & Factories

OldNew
spec/models/code_review_spec.rbspec/models/guard_rail_check_spec.rb
spec/models/code_review_usage_spec.rbspec/models/guard_rail_check_usage_spec.rb
spec/jobs/generate_code_review_job_spec.rbspec/jobs/generate_guard_rail_check_job_spec.rb
spec/factories/code_review_factory.rbspec/factories/guard_rail_check_factory.rb
spec/factories/code_review_usage_factory.rbspec/factories/guard_rail_check_usage_factory.rb

Keep spec/services/ai/code_review_service_spec.rb as-is (service name unchanged).

#1.14 packages.yml

Rename across all tiers:

  • ai_code_review_allowed -> guard_rails_allowed
  • daily_code_review_limit -> daily_guard_rail_limit

#1.15 Activity Log Keys

  • :code_review_requested -> :guard_rail_check_requested
  • :code_review_retried -> :guard_rail_check_retried
  • :code_review_feedback -> :guard_rail_check_feedback
  • :deployment_code_review_started -> :deployment_guard_rails_started

#1.16 WebSocket Event Names

In GenerateGuardRailCheckJob:

  • code_review_started -> guard_rail_check_started
  • code_review_completed -> guard_rail_check_completed
  • code_review_failed -> guard_rail_check_failed

Update corresponding JS WebSocket listeners in GuardRailLoader.jsx.

#1.17 routes.js (auto-generated)

Update route helpers: code_review_project_deployment_path -> guard_rails_project_deployment_path, etc.


Configurable per-project rules that users trigger manually before deploying.

#2.1 New Table: guard_rail_rules

Migration: db/migrate/TIMESTAMP_create_guard_rail_rules.rb

create_table :guard_rail_rules do |t|
  t.string :parent_type, null: false
  t.integer :parent_id, null: false
  t.string :identifier, null: false
  t.string :rule_type, null: false
  t.boolean :enabled, default: true, null: false
  t.boolean :blocking, default: true, null: false
  t.text :configuration  # JSON
  t.integer :position, default: 0
  t.timestamps
end
add_index :guard_rail_rules, :identifier, unique: true, length: 191
add_index :guard_rail_rules, [:parent_type, :parent_id]
add_index :guard_rail_rules, :rule_type, length: 191

Uses polymorphic parent pattern (matches servers, config_files, etc.).

#2.2 New Model: GuardRailRule

File: app/models/guard_rail_rule.rb

  • RULE_TYPES = %w[branch_restriction ai_code_review].freeze (start small, expand later)
  • belongs_to :parent, polymorphic: true
  • serialize :configuration, JSON
  • Scopes: enabled, blocking, ordered, for_type

#2.3 Project Integration

In app/models/project.rb:

  • has_many :guard_rail_rules, as: :parent, dependent: :destroy

#2.4 Guard Rails Executor Service

File: app/services/guard_rails/executor.rb

Orchestrates running all enabled rules for a deployment:

  1. Load project's enabled rules (ordered)
  2. Run each synchronous check (branch restriction)
  3. Dispatch async checks (AI code review)
  4. Collect results (pass/fail/warn/pending per rule)
  5. Return overall status + individual check results

#2.5 Checker Base Class

File: app/services/guard_rails/checkers/base.rb

Interface: .check(deployment, rule) -> CheckResult with success(), failure(), pending() helpers.

#2.6 Branch Restriction Checker

File: app/services/guard_rails/checkers/branch_restriction.rb

Configuration:

{
  "mode": "allowlist",
  "branches": ["main", "release/*"]
}

Synchronous check using File.fnmatch for glob pattern matching against the deployment's branch.

#2.7 AI Code Review Checker (Wrapper)

File: app/services/guard_rails/checkers/ai_code_review.rb

Wraps the existing async AI review flow. Configuration:

{
  "block_on_critical": true
}

#2.8 Guard Rail Rules Controller

File: app/controllers/guard_rail_rules_controller.rb

CRUD for managing rules per project. Actions: index, new, create, edit, update, destroy.

Follows the same pattern as excluded_files_controller.rb, config_files_controller.rb:

  • active_nav :projects, :guard_rails
  • Scoped to @project.guard_rail_rules
  • Standard Rails form handling

#2.9 Views for Rules Settings

Directory: app/views/guard_rail_rules/

  • index.html.haml - list of rule cards with enable/disable toggles (see mockup 2)
  • _form.html.haml - type-specific configuration form (see mockup 3)
  • new.html.haml / edit.html.haml

Uses existing UI patterns: o-listing-items, a-button, m-form-footer, shared/help layout.

#2.10 Project Navigation

Add to app/views/layouts/_project_navigation.html.haml:

%li.m-sidebar-menu__item{class: [active_nav_class(:guard_rails)]}
  = link_to project_guard_rail_rules_path(@project) do
    = icon_tag 'shield'
    Guard Rails

#2.11 Routes

resources :projects do
  resources :guard_rail_rules, except: [:show]
end

#2.12 Integration with Deployment Flow (Opt-in)

The flow remains opt-in, same as current Code Review:

  1. User clicks "Run Guard Rails" in NewDeploymentForm (submits with mode=guard_rails)
  2. CreateController creates a preview deployment
  3. Redirects to Deployments::GuardRailsController#index
  4. Controller runs GuardRails::Executor for synchronous checks immediately
  5. For async checks (AI review), dispatches background job
  6. Results page shows all check outcomes (see mockup 5)
  7. User decides: proceed to deploy, or go back

The GuardRailsController#index view is updated to show the multi-check results page instead of just the AI review. When all checks pass/complete, the "Run Deployment" button appears.

#2.13 NewDeploymentForm Updates

Pass guard rail rules data to the React component:

  • guardRailsEnabled: whether the project has any enabled rules
  • guardRailRulesCount: number of enabled rules
  • Show the Guard Rails section only when rules are configured
  • Keep the daily limit display for AI-based checks

Not in initial scope, but planned:

  • Environment variable validation - check required vars exist
  • Manual approval gates - require team sign-off (needs new guard_rail_approvals table)
  • Migration detection - detect pending migrations in diff

  1. Migration: bin/rails db:migrate succeeds; bin/rails db:rollback works
  2. Tests: bin/rspec passes after all renames
  3. Manual flow: New Deployment Form -> "Run Guard Rails" -> loader -> results page with check outcomes
  4. WebSocket: Verify real-time updates still work with renamed events
  5. API: Verify JSON responses use new key names
  6. Linter: rubocop passes on new/changed files
  7. Routes: bin/rails routes | grep guard_rail shows correct mappings
  8. Settings page: Guard Rail Rules CRUD works (create, edit, enable/disable, delete)
  9. Branch check: Configure a branch restriction, trigger guard rails, verify it passes/blocks correctly
  10. Opt-in verification: Confirm "Deploy" button still works without running guard rails

#Critical files to modify (Phase 1)

  • app/models/code_review.rb -> app/models/guard_rail_check.rb
  • app/models/code_review_usage.rb -> app/models/guard_rail_check_usage.rb
  • app/controllers/deployments/code_review_controller.rb -> app/controllers/deployments/guard_rails_controller.rb
  • app/controllers/deployments/create_controller.rb
  • app/jobs/generate_code_review_job.rb -> app/jobs/generate_guard_rail_check_job.rb
  • app/models/deployment.rb
  • app/models/account.rb
  • app/presenters/deployment_component_presenter.rb
  • app/views/deployments/code_review/ -> app/views/deployments/guard_rails/
  • app/frontend/components/application/CodeReview*.jsx (4 files)
  • app/frontend/components/application/NewDeploymentForm.jsx
  • app/assets/stylesheets/application/ (4 SCSS files)
  • config/routes.rb
  • config/packages.yml
  • app/helpers/deployments_helper.rb
  • app/assets/javascripts/routes.js
  • All spec/factory files for code review

#New files (Phase 2)

  • db/migrate/TIMESTAMP_create_guard_rail_rules.rb
  • app/models/guard_rail_rule.rb
  • app/services/guard_rails/executor.rb
  • app/services/guard_rails/checkers/base.rb
  • app/services/guard_rails/checkers/branch_restriction.rb
  • app/services/guard_rails/checkers/ai_code_review.rb
  • app/controllers/guard_rail_rules_controller.rb
  • app/views/guard_rail_rules/ (index, new, edit, _form)
  • app/views/layouts/_project_navigation.html.haml (add nav item)
  • Corresponding spec files

comments (0)

reviews (0)