Skip to main content

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:

LevelMeaning
errorCritical violation — blocks CI by default (--fail-on error)
warningNotable issue — blocks CI when --fail-on warning
infoInformational — 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