Skip to content

rigor-pundit

Validates Pundit authorize / policy / policy_scope calls against a statically-discovered policy index: the policy class must exist, and an authorize(record, :action) action must correspond to a defined <action>? predicate on the policy. It reads source only — no Pundit runtime dependency.

It ships bundled in rigortype. Activate it under plugins::

plugins:
- rigor-pundit
app/policies/post_policy.rb
class PostPolicy < ApplicationPolicy
def show?; true; end
def update?; true; end
def destroy?; true; end
end
authorize(Post, :show) # info: resolves to PostPolicy#show?
authorize(Post, :destory) # error: PostPolicy#destory? is not defined (did you mean :destroy?)
authorize(Comment, :edit) # error: no policy class CommentPolicy (did you mean … ?)
RuleSeverityFires when
plugin.pundit.policy-callinfoan authorize / policy / policy_scope call resolved to a discovered policy
plugin.pundit.unknown-policy-classerrorthe record maps to a <Type>Policy with no entry in the index (with a did-you-mean)
plugin.pundit.unknown-policy-methoderrorthe policy exists but the :action has no <action>? predicate (lists known predicates + a did-you-mean)
plugin.pundit.load-errorwarningpolicy discovery failed (parse/read error) — once per file

The record maps to a policy by constant name or inferred Nominal[T] (PostPostPolicy); :update normalises to update?. authorize(record) without an action validates only the policy class (the action is controller-runtime-bound).

plugins:
- gem: rigor-pundit
config:
policy_search_paths: ["app/policies"] # default
policy_base_classes: ["ApplicationPolicy"] # default
  • Direct-superclass match only. class AdminPostPolicy < AdminPolicy (where AdminPolicy < ApplicationPolicy) isn’t discovered unless AdminPolicy is added to policy_base_classes.
  • Predicate methods only. Non-? methods, and predicates built with define_method or inherited from concerns, are out of scope.
  • Untyped records pass through. authorize(local, :show) is not validated when local has no inferred Nominal[T].
  • Scope policies are validated for class existence, not for Scope#resolve.

The policy discoverer / index and the contract surfaces this plugin exercises are in the plugin’s README. To write a plugin, see examples/ and the rigor-plugin-author skill.

© 2026 TypedDuck. Licensed under CC BY-SA 4.0.