Policy Files
Policy files let you define architectural contracts for your workspace — rules that ros2inspector will enforce on every run, in CI, and while you develop.
Run ros2inspector validate to check a workspace against a policy locally or in CI.
File format
Create ros2inspector_policy.yaml in your workspace root. A policy is a YAML file with a rules: list. Each rule has a type: field and rule-specific options:
# ros2inspector_policy.yaml
rules:
- type: license
allowed: [Apache-2.0, MIT]
- type: health_threshold
min_score: 70
workspace_min_score: 80
- type: naming
packages:
pattern: "^[a-z][a-z0-9_]*$"
topics:
pattern: "^/?[a-z][a-z0-9_/]*$"
severity: info
- type: no_circular_deps
- type: dependency
forbidden:
- from: navigation2
to: teleop_twist_keyboard
severity: error
- type: topic_connectivity
no_publisher: true
no_subscriber: true
Available rule types
health_threshold
Fail packages (or the whole workspace) whose health score falls below a threshold.
- type: health_threshold
min_score: 70 # Per-package threshold (default: 70)
workspace_min_score: 80 # Workspace aggregate threshold (0 = disabled)
severity: warning # error | warning | info (default: warning)
license
Require every package to declare a license, optionally restricting to an approved list.
- type: license
allowed: [Apache-2.0, MIT, BSD-3-Clause] # Empty = any license is fine
severity: error
naming
Enforce naming patterns for packages, nodes, topics, or services.
- type: naming
packages:
pattern: "^[a-z][a-z0-9_]*$"
severity: warning
nodes:
pattern: "^[a-z][a-z0-9_]*$"
severity: warning
topics:
pattern: "^/?[a-z][a-z0-9_/]*$"
severity: info
services:
pattern: "^/?[a-z][a-z0-9_/]*$"
severity: info
dependency
Forbid or require specific package dependencies.
- type: dependency
forbidden:
- from: navigation2
to: teleop_twist_keyboard
severity: error
- from: production_pkg
to: debug_utils
required:
- package: robot_state_publisher
depends_on: rclcpp
severity: warning
no_circular_deps
Flag any cycle in the package dependency graph.
- type: no_circular_deps
severity: error # default: error
maintainer_required
Require every package to declare a maintainer (and optionally an email).
- type: maintainer_required
require_email: true # default: false
severity: warning
version_not_default
Flag packages still on the placeholder 0.0.0 version.
- type: version_not_default
default_version: "0.0.0" # default: "0.0.0"
severity: info
topic_connectivity
Flag topics that have no publisher (orphan subscriber) or no subscriber (dead output).
- type: topic_connectivity
no_publisher: true # Flag topics with no publisher (default: true)
no_subscriber: true # Flag topics with no subscriber (default: true)
severity_no_publisher: warning # default: warning
severity_no_subscriber: info # default: info
exclude: # Topic names to skip
- /my_debug_topic
- /legacy_output
node_isolation
Flag nodes with no detected communication — no publishers, subscribers, services, or action connections.
- type: node_isolation
severity: warning
skip_dynamic_names: true # Skip nodes flagged as having dynamic topic names (default: true)
service_connectivity
Flag services that are provided but have no callers in the workspace.
- type: service_connectivity
severity: info # default: info
action_connectivity
Flag action servers with no corresponding action client in the workspace.
- type: action_connectivity
severity: warning # default: warning
Severity levels
Every rule supports a severity field:
| Level | Meaning |
|---|---|
error | Critical violation — blocks CI by default (--fail-on error) |
warning | Notable issue — blocks CI when --fail-on warning |
info | Informational — never blocks CI unless --fail-on info |
A complete example
# ros2inspector_policy.yaml
rules:
# Documentation quality
- type: health_threshold
min_score: 65
workspace_min_score: 75
severity: warning
- type: license
allowed: [Apache-2.0, MIT, BSD-3-Clause]
severity: error
- type: maintainer_required
require_email: true
severity: warning
- type: version_not_default
severity: info
# Naming conventions
- type: naming
packages:
pattern: "^[a-z][a-z0-9_]*$"
severity: warning
topics:
pattern: "^/?[a-z][a-z0-9_/]*$"
severity: info
# Dependency governance
- type: no_circular_deps
severity: error
- type: dependency
forbidden:
- from: production_bringup
to: dev_tools
severity: error
# Communication integrity
- type: topic_connectivity
no_publisher: true
severity_no_publisher: warning
exclude: [/rosout, /parameter_events]
- type: node_isolation
severity: warning
- type: action_connectivity
severity: warning
Running validation
# Check against the default policy file
ros2inspector validate
# Use a custom path
ros2inspector validate --policy ci/strict.yaml
# Fail on any warning (strict mode)
ros2inspector validate --fail-on warning
# Machine-readable output
ros2inspector validate --format json | jq '.summary.violations'
CI integration
# .github/workflows/ros2.yml
- name: Architecture policy check
run: ros2inspector validate --policy .ros2inspector/policy.yaml --fail-on warning