Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
jazzy

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro kilted showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro lyrical showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro rolling showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro ardent showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro bouncy showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro crystal showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro eloquent showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro dashing showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro galactic showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro foxy showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro iron showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro lunar showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro jade showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro indigo showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro hydro showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro kinetic showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro melodic showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange

No version for distro noetic showing humble. Known supported distros are highlighted in the buttons above.
Package symbol

autoware_interface_spec_lint package from autoware_core repo

autoware_adapi_adaptors autoware_adapi_specs autoware_core_api autoware_default_adapi autoware_core autoware_agnocast_wrapper autoware_component_interface_admission autoware_component_interface_specs autoware_component_interface_utils autoware_geography_utils autoware_global_parameter_loader autoware_interface_spec_lint autoware_interpolation autoware_kalman_filter autoware_lanelet2_utils autoware_marker_utils autoware_motion_utils autoware_node autoware_object_recognition_utils autoware_osqp_interface autoware_point_types autoware_qos_utils autoware_qp_interface autoware_signal_processing autoware_trajectory autoware_vehicle_info_utils autoware_command_gate autoware_core_control autoware_simple_pure_pursuit autoware_awsim_sensor_kit_description autoware_sample_sensor_kit_description autoware_sample_vehicle_description autoware_core_localization autoware_ekf_localizer autoware_gyro_odometer autoware_localization_util autoware_ndt_scan_matcher autoware_pose_initializer autoware_stop_filter autoware_twist2accel autoware_core_map autoware_lanelet2_map_visualizer autoware_map_height_fitter autoware_map_loader autoware_map_projection_loader autoware_core_perception autoware_euclidean_cluster_object_detector autoware_ground_filter autoware_perception_objects_converter autoware_core_planning autoware_mission_planner autoware_objects_of_interest_marker_interface autoware_path_generator autoware_planning_factor_interface autoware_planning_test_manager autoware_planning_topic_converter autoware_route_handler autoware_velocity_smoother autoware_behavior_velocity_planner autoware_behavior_velocity_planner_common autoware_behavior_velocity_stop_line_module autoware_motion_velocity_obstacle_stop_module autoware_motion_velocity_planner autoware_motion_velocity_planner_common autoware_core_sensing autoware_crop_box_filter autoware_downsample_filters autoware_gnss_poser autoware_vehicle_velocity_converter autoware_pyplot autoware_test_node autoware_test_utils autoware_testing autoware_core_vehicle

ROS Distro
humble

Package Summary

Version 1.10.0
License Apache License 2.0
Build type AMENT_PYTHON
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/autowarefoundation/autoware_core.git
VCS Type git
VCS Version main
Last Updated 2026-09-28
Dev Status DEVELOPED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

Config-driven CI lint for the Autoware component interface specs

Maintainers

  • Yutaka Kondo

Authors

No additional authors.

autoware_interface_spec_lint

Config-driven static and manifest checks for the Autoware component interface specifications defined in autoware_component_interface_specs. This package gives fast, pre-build, human-readable diagnostics that complement the compile-time all_specs_valid<> static assertions: it catches “defined-but-unregistered” specs, version inconsistencies, cross-owner shadowing, heavy-raw topics that must not be versioned, and manifest drift that the compiler alone does not.

Each gate’s severity comes from the committed gate config (config/interface_gates.yaml): off (not run), warn (advisory, prints findings but never fails), or error (fails the build when it reports at least one finding). Every implemented gate is set to error, so a finding now fails CI and the pre-commit hook; only the gates listed under “Honest deferrals” below are off. --warn-only overrides every gate to exit 0 for local advisory runs.

Gates

Gate Input Severity Flags
interface_spec_concept domain headers error a struct with a name[] that is neither a valid topic (Message + depth + reliability + durability) nor a valid service (Service)
spec_registered domain headers error a spec struct not listed in its namespace’s using Specs = std::tuple<...> (unless it carries the suppression marker)
version_consistency headers + manifest error a domain not declaring exactly one version{...}, or a manifest version that disagrees with the header version
qos_consistency headers + manifest error a registered spec whose history / depth / reliability / durability disagrees with its manifest qos block, is missing from the manifest, or names a QoS policy the manifest cannot express
manifest_fresh generator + committed JSON error the rebuilt generator output differs from the committed interface_manifest.json (see the binding-gate note below)
owner_isolation manifest(s) error a non-base-owner manifest entry whose interface name shadows a base-owner (autowarefoundation) entry
no_raw_spec_topic manifest(s) error a versioned topic whose interface name contains a heavy-raw deny substring; services are out of scope

The manifest audits (owner_isolation, no_raw_spec_topic) take a list of manifest dicts so a future vendor-partition manifest can be cross-checked against the base manifest; with the single committed core manifest owner_isolation is vacuously clean.

Binding manifest-freshness gate

The lint’s manifest_fresh can only bind where the manifest generator binary is available; on a plain checkout / pre-commit run it skips gracefully. The binding freshness gate is the specs-package gtest (autoware_component_interface_specs/test/test_manifest.cpp), which regenerates the manifest with the built generator and asserts byte-equality against the committed interface_manifest.json on every build-and-test CI run. Manifest drift is therefore a hard failure regardless of the advisory lint.

Honest deferrals

The following design gate-table entries are declared off in the committed config and are intentionally deferred; enabling one is rejected by the config loader because there is no implementation to run yet.

Gate Why deferred
no_foreign_if_dependency needs per-component provided/required role manifests, which do not exist yet (they arrive with the deploy-time OCI-label manifest track)
profile_compat needs a vendor-specific interface profile that does not exist in this package yet; out of scope for this change
if_usage_coverage runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work
admission_smoke runtime gate; needs runtime introspection data this static-analysis package does not have, deferred to future work

owner_isolation is wired and at error but binds only once a second (vendor-partition) manifest exists to cross-check against. Today the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned, so there is no separate universe-side gate wiring yet.

Suppression contract

A spec struct is exempt from spec_registered when the marker // interface-spec-lint: not-versioned appears on the struct’s own declaration line or on the line directly above it. Use it for a topic that is deliberately not part of the versioned interface set. The marker string is a fixed contract that other packages depend on, so do not change its text.

// interface-spec-lint: not-versioned
struct PointCloudMap {
  using Message = sensor_msgs::msg::PointCloud2;
  static constexpr char name[] = "/map/point_cloud_map";
  // ...
};

Usage

# Lint the core specs with the committed gate config (severities from the config).
ament_autoware_interface_spec_lint

# Advisory local run: print findings but always exit 0.
ament_autoware_interface_spec_lint --warn-only

# Explicit paths and an alternate gate config.
ament_autoware_interface_spec_lint \
  --config common/autoware_interface_spec_lint/config/interface_gates.yaml \
  --spec-dir common/autoware_component_interface_specs/include/autoware/component_interface_specs \
  --manifest common/autoware_component_interface_specs/interface_manifest.json

manifest_fresh

manifest_fresh needs the manifest generator binary. Point at it with --generator <path> or the INTERFACE_MANIFEST_GENERATOR environment variable. When neither is available the check skips gracefully (the binding gate is the specs-package gtest).

export INTERFACE_MANIFEST_GENERATOR=$PWD/build/autoware_component_interface_specs/generate_interface_manifest
ament_autoware_interface_spec_lint \
  --manifest common/autoware_component_interface_specs/interface_manifest.json \
  --generator "$INTERFACE_MANIFEST_GENERATOR"

Gate config

config/interface_gates.yaml maps each gate to a severity and carries the no_raw_spec_topic deny/allow lists and the owner_isolation base owner. The loader rejects an unknown gate name and rejects enabling a deferred gate (it may only be declared off).

CHANGELOG

Changelog for package autoware_interface_spec_lint

1.10.0 (2026-09-28)

  • Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base

  • feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits (#1315)

    * feat(autoware_interface_spec_lint): ratchet interface gates to error and add manifest audits Take the WARN-only lint landed earlier and give it teeth at the CI boundary: findings now fail the build instead of only being printed. Severity mechanism:

    - Add a Severity enum (off/warn/error) and exit_code_for(): a gate fails only at error severity with at least one finding.

    - Add a committed gate config (config/interface_gates.yaml) mapping each gate to a severity, loaded via --config with a packaged default path. The loader rejects unknown gate names and rejects enabling a deferred gate. --warn-only remains as an explicit local/advisory override. New manifest audits (adapted to the committed schema; multi-manifest capable so a future vendor-partition manifest can be cross-checked):

    - owner_isolation(manifests, base_owner): a non-base-owner entry whose interface name shadows a base-owner entry is a finding (vacuously clean on the single core manifest).

    - no_raw_spec_topic(manifests, deny, allow): a versioned topic whose name contains a heavy-raw deny substring is a finding; request/response services are out of scope (the sanctioned differential-map query service is not flagged), and the derived grid obstacle_grid does not match. Ratchet:

    - interface_spec_concept, spec_registered, version_consistency, qos_consistency, manifest_fresh, owner_isolation and no_raw_spec_topic are set to error.

    - The pre-commit hook drops --warn-only, so a finding now fails it. no_raw_spec_topic's heavy-raw deny list still lists the retired point_cloud_map topic name; the committed manifest no longer carries that entry, so the check reports no findings for it. manifest_fresh stays advisory locally (skips without a generator) and leans on the specs package's own committed-manifest gtest and CMake compile definition -- both already in place on this branch's base -- for the hard drift gate in build-and-test CI. Honest deferrals: no_foreign_if_dependency / profile_compat (need per-component role manifests / a vendor-specific interface profile that does not exist yet) and the runtime gates if_usage_coverage / admission_smoke (need runtime introspection data this static-analysis package does not have) are kept off with documented reasons. No universe-side gate wiring yet: the universe versioned surface is exactly the core re-exports (single version authority in core) and universe-owned specs are unversioned until a future vendor-partition manifest lands.

    * fix(autoware_interface_spec_lint): drop the 0.x-only major-version policy version_consistency runs at error severity once the gates ratchet, so the hard-coded 'MAJOR must be 0' finding would fail CI on the first legitimate MAJOR bump by construction. Keep the load-bearing half of the check (header-vs-manifest version agreement) and leave bump discipline to review.

    * fix(autoware_interface_spec_lint): reject empty gate configs and cover run()'s exit code An empty (or absent) [gates:]{.title-ref} key loaded successfully with every gate defaulting to off, so the lint would report zero findings and exit 0 against any tree regardless of its actual state. load_config() now raises ValueError when the parsed severities map is empty, matching the fail-closed contract the loader already applies to unknown gate names and deferred-gate misuse. test_config.py also pins qos_consistency into the set of gates the committed config ratchets to error severity; the existing assertion listed every implemented gate except that one. No prior test drove run() itself over a violating tree with an error-severity gate enabled: test_severity.py covers exit_code_for in isolation, and test_acceptance.py only pins the converse (a clean tree exits 0). Add test_run_exit_code.py to close that gap and assert run() returns 1 on an error-severity finding, stays at 0 under warn_only, and stays at 0 when the only finding is warn severity.

    * test(autoware_interface_spec_lint): drop the duplicate out-of-scope service test test_differential_pcd_map_service_stays_out_of_scope fed the identical manifest entry to the identical call and asserted the identical result as test_service_with_denied_substring_is_out_of_scope, so it added no coverage. Its comment also misdescribed what it guarded: the deny entry it was added alongside, "point_cloud_map", is not a substring of /map/get_differential_pointcloud_map at all -- the pre-existing "pointcloud_map" entry is the one that matches. Since no_raw_spec_topic scopes on kind == "topic" and never on the name, one service case covers every deny spelling, so fold that reasoning into the surviving test's comment. Addresses a review comment on #1315. ---------

File truncated at 100 lines see the full file

Package Dependencies

System Dependencies

Dependant Packages

No known dependants.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged autoware_interface_spec_lint at Robotics Stack Exchange