rosotacom-dev 2.5.dev37__tar.gz → 2.5.dev39__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/DEVELOPMENT_PRINCIPLES.md +8 -2
  2. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/PKG-INFO +1 -1
  3. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/install.sh +13 -3
  4. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/justfile +1 -1
  5. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/pyproject.toml +0 -2
  6. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/cli.py +14 -19
  7. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +32 -2
  8. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +8 -2
  9. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +49 -36
  10. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/PKG-INFO +1 -1
  11. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/SOURCES.txt +2 -2
  12. rosotacom_dev-2.5.dev39/src/rosotacom_dev.egg-info/entry_points.txt +2 -0
  13. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/scm_file_list.json +2 -2
  14. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
  15. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_package_metadata.py +11 -3
  16. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_catmux_pane_logging.py +74 -0
  17. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_cli.py +7 -13
  18. rosotacom_dev-2.5.dev39/tests/unit/test_qos_fallback_logging.py +139 -0
  19. rosotacom_dev-2.5.dev39/tests/unit/test_relay_optional_parameters.py +176 -0
  20. rosotacom_dev-2.5.dev37/run_session_in_container.py +0 -9
  21. rosotacom_dev-2.5.dev37/src/rosotacom_dev.egg-info/entry_points.txt +0 -4
  22. rosotacom_dev-2.5.dev37/stop_session_in_container.py +0 -9
  23. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.devcontainer/devcontainer.json.template +0 -0
  24. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.devcontainer/re_generate_devcontainer_json.py +0 -0
  25. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/CODEOWNERS +0 -0
  26. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
  27. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
  28. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
  29. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
  30. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
  31. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
  32. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
  33. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
  34. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  35. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/actions/setup-just/action.yml +0 -0
  36. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/dependabot.yml +0 -0
  37. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/workflows/benchmark-calibrate.yml +0 -0
  38. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/workflows/benchmark-gate.yml +0 -0
  39. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/workflows/dev-release.yml +0 -0
  40. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/workflows/image-scan.yml +0 -0
  41. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/workflows/nightly-e2e.yml +0 -0
  42. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/workflows/pr-lightweight.yml +0 -0
  43. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/workflows/pr-merge-gate.yml +0 -0
  44. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.github/workflows/release.yml +0 -0
  45. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/.pre-commit-config.yaml +0 -0
  46. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/AGENTS.md +0 -0
  47. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/CONCURRENCY.md +0 -0
  48. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/CONTRIBUTING.md +0 -0
  49. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/LICENSE.txt +0 -0
  50. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/MANIFEST.in +0 -0
  51. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/README.md +0 -0
  52. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/budgets.jsonl +0 -0
  53. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/calibration/README.md +0 -0
  54. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/calibration/capacity-size-tight-cyclone.json +0 -0
  55. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
  56. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/calibration/probe-loss-nominal-cyclone.json +0 -0
  57. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/calibration/probe-loss-tight-cyclone.json +0 -0
  58. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/calibration/probe-loss-tight-fastdds.json +0 -0
  59. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/calibration/probe-loss-tight-zenoh.json +0 -0
  60. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/codecov.yml +0 -0
  61. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/deployment-configuration.md +0 -0
  62. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/benchmark-ab.md +0 -0
  63. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/benchmark-bag-as-load.md +0 -0
  64. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/ci.md +0 -0
  65. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/ffmpeg-keyframes.md +0 -0
  66. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/findings/README.md +0 -0
  67. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
  68. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/findings/delay-alone-no-loss.md +0 -0
  69. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/findings/head-of-line-irregularity.md +0 -0
  70. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
  71. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/findings/lighter-message-loss.md +0 -0
  72. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
  73. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/forensics-report.md +0 -0
  74. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/geo-link-map.md +0 -0
  75. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/github-repository-settings.md +0 -0
  76. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/link-bandwidth.md +0 -0
  77. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/link-trace.md +0 -0
  78. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/owner-runbook.md +0 -0
  79. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/performance-bands.md +0 -0
  80. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/playbooks/README.md +0 -0
  81. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/quality-model.md +0 -0
  82. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/release-notes/TEMPLATE.md +0 -0
  83. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/release-notes/v2.1.md +0 -0
  84. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/release-notes/v2.2.md +0 -0
  85. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/release-notes/v2.3.md +0 -0
  86. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/release-notes/v2.4.md +0 -0
  87. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/release.md +0 -0
  88. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
  89. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/rfcs/0002-expectation-concepts.md +0 -0
  90. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/rfcs/0003-metric-backbone.md +0 -0
  91. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/rfcs/0004-network-profiles.md +0 -0
  92. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
  93. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/rfcs/0006-dynamic-qos.md +0 -0
  94. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/rfcs/0007-regression-gate.md +0 -0
  95. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/rfcs/README.md +0 -0
  96. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/testing.md +0 -0
  97. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/docs/work-items.md +0 -0
  98. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/media/control_center.png +0 -0
  99. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/media/echo_test.png +0 -0
  100. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/media/forensics-report-example.png +0 -0
  101. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/media/host.png +0 -0
  102. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/media/vehicle.png +0 -0
  103. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/requirements.txt +0 -0
  104. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/rosotacom.yaml +0 -0
  105. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/session-configuration.md +0 -0
  106. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/setup.cfg +0 -0
  107. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/__init__.py +0 -0
  108. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/__main__.py +0 -0
  109. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/anonymize.py +0 -0
  110. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/bag_ground_truth.py +0 -0
  111. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/benched_set.py +0 -0
  112. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/benchmark.py +0 -0
  113. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/benchmark_delta.py +0 -0
  114. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/bundle_check.py +0 -0
  115. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/cli_benchmark.py +0 -0
  116. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/deployment.py +0 -0
  117. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/ffmpeg_packet.py +0 -0
  118. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/forensics.py +0 -0
  119. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/geomap.py +0 -0
  120. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/image_cache.py +0 -0
  121. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/network_profiles.py +0 -0
  122. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/network_shaper.py +0 -0
  123. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/plots.py +0 -0
  124. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/py.typed +0 -0
  125. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/benched-set.yaml +0 -0
  126. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/.gitignore +0 -0
  127. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/README.md +0 -0
  128. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/__init__.py +0 -0
  129. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
  130. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
  131. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/profiles.yaml +0 -0
  132. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/ros2docker.json +0 -0
  133. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
  134. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
  135. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
  136. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
  137. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
  138. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
  139. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
  140. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
  141. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
  142. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
  143. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
  144. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
  145. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
  146. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
  147. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
  148. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
  149. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  150. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
  151. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
  152. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
  153. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
  154. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
  155. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
  156. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
  157. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
  158. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
  159. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  160. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
  161. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
  162. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
  163. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
  164. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
  165. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
  166. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
  167. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
  168. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
  169. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
  170. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
  171. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
  172. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
  173. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
  174. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
  175. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
  176. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
  177. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
  178. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
  179. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
  180. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
  181. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
  182. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
  183. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
  184. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
  185. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
  186. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
  187. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
  188. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
  189. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
  190. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
  191. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
  192. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
  193. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
  194. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
  195. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
  196. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
  197. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
  198. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
  199. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
  200. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
  201. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
  202. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
  203. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ros2docker.json.example +0 -0
  204. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
  205. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
  206. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
  207. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
  208. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
  209. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
  210. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
  211. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
  212. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
  213. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/cyclonedds_local_participants.xml.template +0 -0
  214. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
  215. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
  216. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
  217. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
  218. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
  219. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
  220. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
  221. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
  222. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
  223. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
  224. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
  225. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
  226. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
  227. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
  228. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
  229. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
  230. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
  231. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
  232. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
  233. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
  234. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
  235. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
  236. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
  237. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
  238. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
  239. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
  240. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
  241. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
  242. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
  243. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
  244. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
  245. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
  246. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
  247. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
  248. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
  249. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
  250. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
  251. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
  252. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
  253. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
  254. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
  255. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
  256. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
  257. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
  258. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
  259. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
  260. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
  261. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
  262. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
  263. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
  264. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +0 -0
  265. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
  266. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
  267. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
  268. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
  269. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
  270. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
  271. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
  272. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
  273. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
  274. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
  275. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
  276. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
  277. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
  278. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
  279. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
  280. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
  281. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
  282. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
  283. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
  284. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
  285. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
  286. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +0 -0
  287. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
  288. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
  289. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
  290. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/status_eval.py +0 -0
  291. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/stream_stats.py +0 -0
  292. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/trace_profiles.py +0 -0
  293. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/transit.py +0 -0
  294. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom/video_quality.py +0 -0
  295. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
  296. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/requires.txt +0 -0
  297. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
  298. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/terminology.md +0 -0
  299. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_benched_set_registry.py +0 -0
  300. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_findings.py +0 -0
  301. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_markdown_links.py +0 -0
  302. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_ota_source_bundle.py +0 -0
  303. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_packaged_resources.py +0 -0
  304. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_profile_covers_generated_commands.py +0 -0
  305. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_pytest_policy.py +0 -0
  306. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_readme_examples.py +0 -0
  307. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_security_maintenance_config.py +0 -0
  308. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_session_configuration_doc.py +0 -0
  309. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_session_template_substitution.py +0 -0
  310. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/contract/test_workflow_contracts.py +0 -0
  311. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/e2e/conftest.py +0 -0
  312. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/e2e/test_anonymize_e2e.py +0 -0
  313. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/e2e/test_benchmark_ab.py +0 -0
  314. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/e2e/test_benchmark_capacity.py +0 -0
  315. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/e2e/test_benchmark_replay.py +0 -0
  316. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/e2e/test_parallel_smoke.py +0 -0
  317. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/e2e/test_smoke.py +0 -0
  318. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/e2e/test_timeline_stepping.py +0 -0
  319. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/e2e/test_video_quality_e2e.py +0 -0
  320. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/sessions/generate_rmw_matrix.py +0 -0
  321. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
  322. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
  323. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
  324. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
  325. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
  326. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_anonymize.py +0 -0
  327. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_bag_ground_truth.py +0 -0
  328. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_benched_set.py +0 -0
  329. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_benchmark.py +0 -0
  330. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_benchmark_delta.py +0 -0
  331. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_bundle_check.py +0 -0
  332. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_cli_benchmark.py +0 -0
  333. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_concurrency.py +0 -0
  334. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_deployment.py +0 -0
  335. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_ffmpeg_packet.py +0 -0
  336. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_forensics.py +0 -0
  337. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_geomap.py +0 -0
  338. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_image_cache.py +0 -0
  339. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_link_bytes.py +0 -0
  340. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_link_trace.py +0 -0
  341. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_network_profiles.py +0 -0
  342. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_network_shaper.py +0 -0
  343. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_ota_unwrapper.py +0 -0
  344. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_ota_wrapper.py +0 -0
  345. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_ota_xml.py +0 -0
  346. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_plots.py +0 -0
  347. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_session_pipeline.py +0 -0
  348. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_stage_latency.py +0 -0
  349. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_status_eval.py +0 -0
  350. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_status_overview.py +0 -0
  351. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_status_overview_observer.py +0 -0
  352. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_stream_stats.py +0 -0
  353. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_trace_profiles.py +0 -0
  354. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_transit.py +0 -0
  355. {rosotacom_dev-2.5.dev37 → rosotacom_dev-2.5.dev39}/tests/unit/test_video_quality.py +0 -0
@@ -13,10 +13,16 @@ A change is complete only if:
13
13
 
14
14
  ## Compatibility Policy
15
15
 
16
- Preserve documented CLI behavior and the legacy `start_rosotacom` and
17
- `stop_rosotacom` entry points. Do not add silent aliases for removed behavior
16
+ Preserve documented CLI behavior. Do not add silent aliases for removed behavior
18
17
  unless a migration explicitly requires them.
19
18
 
19
+ `rosotacom` is the only console script this package installs. The
20
+ `start_rosotacom` / `stop_rosotacom` entry points were the one standing
21
+ exception to rule 6 above; they were removed on 2026-08-14 because they were
22
+ nothing but `rosotacom start` and `rosotacom stop` under a second name, and a
23
+ second name is what makes a stale shim on a machine indistinguishable from a
24
+ live command. `rosotacom doctor` reports one that is still lying around.
25
+
20
26
  ## Testing Policy
21
27
 
22
28
  Test public behavior and contracts.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rosotacom-dev
3
- Version: 2.5.dev37
3
+ Version: 2.5.dev39
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -85,8 +85,18 @@ echo " just setup"
85
85
  if [[ "$INSTALL_GLOBAL_SYMLINKS" == true ]]; then
86
86
  mkdir -p "$BIN_DIR"
87
87
  ln -sf "$VENV_DIR/bin/rosotacom" "$BIN_DIR/rosotacom"
88
- ln -sf "$VENV_DIR/bin/start_rosotacom" "$BIN_DIR/start_rosotacom"
89
- ln -sf "$VENV_DIR/bin/stop_rosotacom" "$BIN_DIR/stop_rosotacom"
90
88
  echo
91
- echo "Installed legacy global symlinks into: $BIN_DIR"
89
+ echo "Installed global symlink into: $BIN_DIR"
90
+ # `start_rosotacom` / `stop_rosotacom` were entry points until 2026-08-14. A
91
+ # machine that ran an older install.sh still has their symlinks, and they now
92
+ # point into a venv whose package no longer provides them. Only links this
93
+ # script could have written are touched — into THIS checkout's venv, never a
94
+ # file or a link belonging to something else.
95
+ for retired in start_rosotacom stop_rosotacom; do
96
+ link="$BIN_DIR/$retired"
97
+ if [[ -L "$link" && "$(readlink -- "$link")" == "$VENV_DIR/bin/$retired" ]]; then
98
+ rm -- "$link"
99
+ echo "Removed retired symlink: $link (use 'rosotacom start' / 'rosotacom stop')"
100
+ fi
101
+ done
92
102
  fi
@@ -19,7 +19,7 @@ format:
19
19
  lint:
20
20
  {{python}} -m ruff check .
21
21
  {{python}} -m ruff format --check .
22
- {{python}} -m py_compile src/rosotacom/*.py run_session_in_container.py stop_session_in_container.py
22
+ {{python}} -m py_compile src/rosotacom/*.py
23
23
 
24
24
  typecheck:
25
25
  {{python}} -m mypy
@@ -61,8 +61,6 @@ plots = [
61
61
 
62
62
  [project.scripts]
63
63
  rosotacom = "rosotacom.cli:main"
64
- start_rosotacom = "rosotacom.cli:start_compat_main"
65
- stop_rosotacom = "rosotacom.cli:stop_compat_main"
66
64
 
67
65
  [tool.setuptools]
68
66
  include-package-data = true
@@ -5676,18 +5676,21 @@ def doctor(args: argparse.Namespace) -> int:
5676
5676
  except Exception as exc: # noqa: BLE001 - doctor reports all setup failures.
5677
5677
  line("ERROR", "config", str(exc))
5678
5678
 
5679
- stale = Path.home() / ".local" / "bin" / "start_rosotacom"
5680
- if stale.exists() or stale.is_symlink():
5681
- try:
5682
- target = stale.resolve(strict=False)
5683
- except OSError:
5684
- target = Path(os.readlink(stale))
5685
- if PROJECT_DIR not in [target, *target.parents]:
5686
- line("WARN", "legacy start_rosotacom", f"{stale} points to {target}, outside this checkout")
5687
- else:
5688
- line("OK", "legacy start_rosotacom", f"{stale} points to this checkout")
5679
+ # `start_rosotacom` / `stop_rosotacom` were entry points of this package until
5680
+ # 2026-08-14; `rosotacom start` and `rosotacom stop` are the command. A shim
5681
+ # left behind keeps dispatching through whichever venv it points at, which is
5682
+ # exactly the stale-install confusion this check used to report — so it is a
5683
+ # leftover to delete now, not a second way to run this.
5684
+ retired = [Path.home() / ".local" / "bin" / name for name in ("start_rosotacom", "stop_rosotacom")]
5685
+ leftovers = [p for p in retired if p.exists() or p.is_symlink()]
5686
+ if leftovers:
5687
+ line(
5688
+ "WARN",
5689
+ "retired entry points",
5690
+ f"{', '.join(str(p) for p in leftovers)} — remove; `rosotacom start` / `rosotacom stop` replaced them",
5691
+ )
5689
5692
  else:
5690
- line("INFO", "legacy start_rosotacom", "no global legacy symlink found")
5693
+ line("OK", "retired entry points", "no start_rosotacom/stop_rosotacom shim left")
5691
5694
 
5692
5695
  tmux = shutil.which("tmux")
5693
5696
  if tmux:
@@ -9757,13 +9760,5 @@ def main(argv: list[str] | None = None) -> int:
9757
9760
  return 1
9758
9761
 
9759
9762
 
9760
- def start_compat_main() -> int:
9761
- return main(["start", *sys.argv[1:]])
9762
-
9763
-
9764
- def stop_compat_main() -> int:
9765
- return main(["stop", *sys.argv[1:]])
9766
-
9767
-
9768
9763
  if __name__ == "__main__":
9769
9764
  raise SystemExit(main())
@@ -61,8 +61,8 @@ class BaseBridgeRelay(Node, PairRefreshMixin):
61
61
  self.qos_config_file = self.declare_parameter('qos_config_file', '').value
62
62
 
63
63
  # Optional parameters with defaults
64
- self.source_names = self.declare_parameter('source_names', rclpy.Parameter.Type.STRING_ARRAY).value or []
65
- self.target_names = self.declare_parameter('target_names', rclpy.Parameter.Type.STRING_ARRAY).value or []
64
+ self.source_names = self.declare_optional_string_array('source_names')
65
+ self.target_names = self.declare_optional_string_array('target_names')
66
66
 
67
67
  # Derived classes can declare additional parameters here (must happen before initialize_node()).
68
68
  self.declare_additional_parameters()
@@ -73,6 +73,36 @@ class BaseBridgeRelay(Node, PairRefreshMixin):
73
73
  # Create timer for periodic refresh of invalid pairs
74
74
  self.init_pair_refresh(period_s=5.0, log_prefix=self.node_role)
75
75
 
76
+ def declare_optional_string_array(self, name: str) -> list:
77
+ """Declare an optional STRING_ARRAY that reads as [] rather than as unset.
78
+
79
+ Declaring a type without a value leaves the parameter
80
+ PARAMETER_NOT_SET. This node never notices — it reads the value once,
81
+ here, and an unset parameter simply yields None. Everything *else*
82
+ notices: reading a not-set parameter raises, and rclpy's parameter
83
+ service logs one warning per read against this node,
84
+
85
+ [WARN] [ota_relay_out]: Failed to get parameters: The parameter
86
+ 'source_names' is not initialized: source_names
87
+
88
+ which anything that enumerates parameters then produces on a timer. A
89
+ Foxglove bridge with a parameter panel open put 107 of those lines into
90
+ a single pane in one session — the kind of noise that hides the message
91
+ somebody actually needs to see.
92
+
93
+ A plain default cannot express this: `declare_parameter(name, [])`
94
+ infers the type from the value, and an empty list satisfies the
95
+ BYTE_ARRAY test first (`all(...)` is true for an empty sequence). The
96
+ parameter would be typed BYTE_ARRAY and the real string array refused
97
+ later with "Wrong parameter type, expected '5' got '9'". Declaring the
98
+ type and then setting the empty value keeps it STRING_ARRAY, so a wrong
99
+ type is still rejected and an override still wins.
100
+ """
101
+ self.declare_parameter(name, rclpy.Parameter.Type.STRING_ARRAY)
102
+ if self.get_parameter_or(name).type_ == rclpy.Parameter.Type.NOT_SET:
103
+ self.set_parameters([rclpy.Parameter(name, rclpy.Parameter.Type.STRING_ARRAY, [])])
104
+ return self.get_parameter(name).value
105
+
76
106
  def initialize_node(self):
77
107
  """Initialize node with resolved topics and QoS configuration."""
78
108
  try:
@@ -139,7 +139,13 @@ def get_topic_qos(logger, qos_config: dict, topic_name: str, role_name: str):
139
139
  Additionally supports a fallback lookup: if no exact match for topic_name exists
140
140
  in qos_config['topics'], we look for the most specific configured base topic key
141
141
  that matches as a path segment within topic_name (e.g. '/tf' for
142
- '/shuttle_ella/tf/restamped'). If such a fallback is used, it is always logged.
142
+ '/shuttle_ella/tf/restamped'). Such a fallback is logged at debug level: it is
143
+ the designed path, not a degradation. Every processing stage appends a suffix,
144
+ so a session that uses framebridge, latching or a transport reaches it for most
145
+ of its topics, and a definition that declares QoS on the base topic and lets the
146
+ processed names inherit it is doing exactly what the schema intends. Logged as a
147
+ warning it was two lines per topic per peer at every start — enough noise around
148
+ a bring-up to bury an actual fault.
143
149
  """
144
150
  default = qos_config.get('default', {})
145
151
 
@@ -151,7 +157,7 @@ def get_topic_qos(logger, qos_config: dict, topic_name: str, role_name: str):
151
157
  if topic_name not in topics_cfg:
152
158
  base_match = _find_best_base_topic_match(topics_cfg, topic_name)
153
159
  if base_match is not None:
154
- logger.warning(
160
+ logger.debug(
155
161
  f"[dds_qos] No exact QoS match for topic='{topic_name}'. "
156
162
  f"Falling back to base topic='{base_match}'."
157
163
  )
@@ -534,6 +534,19 @@ windows:
534
534
  - commands:
535
535
  - if [ '${ipx_4_topics}' = "None" ]; then exit; fi
536
536
  - ros2 run com_py image_pixel_capper --ros-args -p topics:=[${ipx_4_topics}] -p max_pixels_preset:=${ipx_4_preset} -p qos_config_file:='${qos_config_file}'
537
+ # `if ...; then ...; fi`, never `[[ ... ]] && ...`, for the optional argument
538
+ # lines below. catmux sends every one of these to an interactive shell, and
539
+ # `catmux_log_setup.sh` hooks the pane-exit recorder into PROMPT_COMMAND — so
540
+ # it sees the status of each line, not just of the node the pane finally runs.
541
+ # `&&` short-circuits to status 1 whenever the option is unset, which is the
542
+ # normal case for every option a session does not override, so each of these
543
+ # lines wrote itself into `pane_failures.log` as a dead pane:
544
+ #
545
+ # pane=13-IT/0 exit=1 command=[[ "None" != "None" ]] && args+=(-p "ut.foxglove.bit_rate:=None")
546
+ #
547
+ # A peer then reported `STARTUP CHECK FAILED ... 4 pane(s) exited` on every
548
+ # start while nothing was wrong, which is the one thing that check must not
549
+ # do: it exists to make a genuinely dead pane visible in seconds.
537
550
  - name: IT
538
551
  if: it
539
552
  layout: even-vertical
@@ -542,15 +555,15 @@ windows:
542
555
  - if [ '${it_1_topic}' = "None" ]; then exit; fi
543
556
  - if [[ "${it_1_topic}" == *"/compressed"* ]]; then it_in_transport="compressed"; else it_in_transport="raw"; fi
544
557
  - args=(ros2 run image_transport republish --ros-args -r __node:=republish1 -p in_transport:=${it_in_transport})
545
- - '[[ "${it_1_transport}" != "None" ]] && args+=(-p "out_transport:=${it_1_transport}")'
546
- - '[[ "${it_1_compressed_jpeg_quality}" != "None" ]] && args+=(-p "ut.compressed.jpeg_quality:=${it_1_compressed_jpeg_quality}")'
547
- - '[[ "${it_1_ffmpeg_gop_size}" != "None" ]] && args+=(-p "ut.ffmpeg.gop_size:=${it_1_ffmpeg_gop_size}")'
548
- - '[[ "${it_1_ffmpeg_encoder_av_options}" != "None" ]] && args+=(-p "ut.ffmpeg.encoder_av_options:=${it_1_ffmpeg_encoder_av_options}")'
549
- - '[[ "${it_1_ffmpeg_bit_rate}" != "None" ]] && args+=(-p "ut.ffmpeg.bit_rate:=${it_1_ffmpeg_bit_rate}")'
550
- - '[[ "${it_1_foxglove_gop_size}" != "None" ]] && args+=(-p "ut.foxglove.gop_size:=${it_1_foxglove_gop_size}")'
551
- - '[[ "${it_1_foxglove_encoder_av_options}" != "None" ]] && args+=(-p "ut.foxglove.encoder_av_options:=${it_1_foxglove_encoder_av_options}")'
552
- - '[[ "${it_1_foxglove_bit_rate}" != "None" ]] && args+=(-p "ut.foxglove.bit_rate:=${it_1_foxglove_bit_rate}")'
553
- - '[[ "${it_1_foxglove_qmax}" != "None" ]] && args+=(-p "ut.foxglove.qmax:=${it_1_foxglove_qmax}")'
558
+ - 'if [[ "${it_1_transport}" != "None" ]]; then args+=(-p "out_transport:=${it_1_transport}"); fi'
559
+ - 'if [[ "${it_1_compressed_jpeg_quality}" != "None" ]]; then args+=(-p "ut.compressed.jpeg_quality:=${it_1_compressed_jpeg_quality}"); fi'
560
+ - 'if [[ "${it_1_ffmpeg_gop_size}" != "None" ]]; then args+=(-p "ut.ffmpeg.gop_size:=${it_1_ffmpeg_gop_size}"); fi'
561
+ - 'if [[ "${it_1_ffmpeg_encoder_av_options}" != "None" ]]; then args+=(-p "ut.ffmpeg.encoder_av_options:=${it_1_ffmpeg_encoder_av_options}"); fi'
562
+ - 'if [[ "${it_1_ffmpeg_bit_rate}" != "None" ]]; then args+=(-p "ut.ffmpeg.bit_rate:=${it_1_ffmpeg_bit_rate}"); fi'
563
+ - 'if [[ "${it_1_foxglove_gop_size}" != "None" ]]; then args+=(-p "ut.foxglove.gop_size:=${it_1_foxglove_gop_size}"); fi'
564
+ - 'if [[ "${it_1_foxglove_encoder_av_options}" != "None" ]]; then args+=(-p "ut.foxglove.encoder_av_options:=${it_1_foxglove_encoder_av_options}"); fi'
565
+ - 'if [[ "${it_1_foxglove_bit_rate}" != "None" ]]; then args+=(-p "ut.foxglove.bit_rate:=${it_1_foxglove_bit_rate}"); fi'
566
+ - 'if [[ "${it_1_foxglove_qmax}" != "None" ]]; then args+=(-p "ut.foxglove.qmax:=${it_1_foxglove_qmax}"); fi'
554
567
  - if [[ "${it_1_outgoing_suffix}" != "None" ]]; then outgoing_suffix="${it_1_outgoing_suffix}"; else outgoing_suffix="${it_1_transport}"; fi
555
568
  - if [[ "${it_in_transport}" == "raw" ]]; then in_remap="in"; else in_remap="in/${it_in_transport}"; fi
556
569
  - args+=(--remap "${in_remap}:=${it_1_topic}" --remap "out/${it_1_transport}:=${it_1_topic}/${outgoing_suffix}")
@@ -560,15 +573,15 @@ windows:
560
573
  - if [ '${it_2_topic}' = "None" ]; then exit; fi
561
574
  - if [[ "${it_2_topic}" == *"/compressed"* ]]; then it_in_transport="compressed"; else it_in_transport="raw"; fi
562
575
  - args=(ros2 run image_transport republish --ros-args -r __node:=republish2 -p in_transport:=${it_in_transport})
563
- - '[[ "${it_2_transport}" != "None" ]] && args+=(-p "out_transport:=${it_2_transport}")'
564
- - '[[ "${it_2_compressed_jpeg_quality}" != "None" ]] && args+=(-p "ut.compressed.jpeg_quality:=${it_2_compressed_jpeg_quality}")'
565
- - '[[ "${it_2_ffmpeg_gop_size}" != "None" ]] && args+=(-p "ut.ffmpeg.gop_size:=${it_2_ffmpeg_gop_size}")'
566
- - '[[ "${it_2_ffmpeg_encoder_av_options}" != "None" ]] && args+=(-p "ut.ffmpeg.encoder_av_options:=${it_2_ffmpeg_encoder_av_options}")'
567
- - '[[ "${it_2_ffmpeg_bit_rate}" != "None" ]] && args+=(-p "ut.ffmpeg.bit_rate:=${it_2_ffmpeg_bit_rate}")'
568
- - '[[ "${it_2_foxglove_gop_size}" != "None" ]] && args+=(-p "ut.foxglove.gop_size:=${it_2_foxglove_gop_size}")'
569
- - '[[ "${it_2_foxglove_encoder_av_options}" != "None" ]] && args+=(-p "ut.foxglove.encoder_av_options:=${it_2_foxglove_encoder_av_options}")'
570
- - '[[ "${it_2_foxglove_bit_rate}" != "None" ]] && args+=(-p "ut.foxglove.bit_rate:=${it_2_foxglove_bit_rate}")'
571
- - '[[ "${it_2_foxglove_qmax}" != "None" ]] && args+=(-p "ut.foxglove.qmax:=${it_2_foxglove_qmax}")'
576
+ - 'if [[ "${it_2_transport}" != "None" ]]; then args+=(-p "out_transport:=${it_2_transport}"); fi'
577
+ - 'if [[ "${it_2_compressed_jpeg_quality}" != "None" ]]; then args+=(-p "ut.compressed.jpeg_quality:=${it_2_compressed_jpeg_quality}"); fi'
578
+ - 'if [[ "${it_2_ffmpeg_gop_size}" != "None" ]]; then args+=(-p "ut.ffmpeg.gop_size:=${it_2_ffmpeg_gop_size}"); fi'
579
+ - 'if [[ "${it_2_ffmpeg_encoder_av_options}" != "None" ]]; then args+=(-p "ut.ffmpeg.encoder_av_options:=${it_2_ffmpeg_encoder_av_options}"); fi'
580
+ - 'if [[ "${it_2_ffmpeg_bit_rate}" != "None" ]]; then args+=(-p "ut.ffmpeg.bit_rate:=${it_2_ffmpeg_bit_rate}"); fi'
581
+ - 'if [[ "${it_2_foxglove_gop_size}" != "None" ]]; then args+=(-p "ut.foxglove.gop_size:=${it_2_foxglove_gop_size}"); fi'
582
+ - 'if [[ "${it_2_foxglove_encoder_av_options}" != "None" ]]; then args+=(-p "ut.foxglove.encoder_av_options:=${it_2_foxglove_encoder_av_options}"); fi'
583
+ - 'if [[ "${it_2_foxglove_bit_rate}" != "None" ]]; then args+=(-p "ut.foxglove.bit_rate:=${it_2_foxglove_bit_rate}"); fi'
584
+ - 'if [[ "${it_2_foxglove_qmax}" != "None" ]]; then args+=(-p "ut.foxglove.qmax:=${it_2_foxglove_qmax}"); fi'
572
585
  - if [[ "${it_2_outgoing_suffix}" != "None" ]]; then outgoing_suffix="${it_2_outgoing_suffix}"; else outgoing_suffix="${it_2_transport}"; fi
573
586
  - if [[ "${it_in_transport}" == "raw" ]]; then in_remap="in"; else in_remap="in/${it_in_transport}"; fi
574
587
  - args+=(--remap "${in_remap}:=${it_2_topic}" --remap "out/${it_2_transport}:=${it_2_topic}/${outgoing_suffix}")
@@ -578,15 +591,15 @@ windows:
578
591
  - if [ '${it_3_topic}' = "None" ]; then exit; fi
579
592
  - if [[ "${it_3_topic}" == *"/compressed"* ]]; then it_in_transport="compressed"; else it_in_transport="raw"; fi
580
593
  - args=(ros2 run image_transport republish --ros-args -r __node:=republish3 -p in_transport:=${it_in_transport})
581
- - '[[ "${it_3_transport}" != "None" ]] && args+=(-p "out_transport:=${it_3_transport}")'
582
- - '[[ "${it_3_compressed_jpeg_quality}" != "None" ]] && args+=(-p "ut.compressed.jpeg_quality:=${it_3_compressed_jpeg_quality}")'
583
- - '[[ "${it_3_ffmpeg_gop_size}" != "None" ]] && args+=(-p "ut.ffmpeg.gop_size:=${it_3_ffmpeg_gop_size}")'
584
- - '[[ "${it_3_ffmpeg_encoder_av_options}" != "None" ]] && args+=(-p "ut.ffmpeg.encoder_av_options:=${it_3_ffmpeg_encoder_av_options}")'
585
- - '[[ "${it_3_ffmpeg_bit_rate}" != "None" ]] && args+=(-p "ut.ffmpeg.bit_rate:=${it_3_ffmpeg_bit_rate}")'
586
- - '[[ "${it_3_foxglove_gop_size}" != "None" ]] && args+=(-p "ut.foxglove.gop_size:=${it_3_foxglove_gop_size}")'
587
- - '[[ "${it_3_foxglove_encoder_av_options}" != "None" ]] && args+=(-p "ut.foxglove.encoder_av_options:=${it_3_foxglove_encoder_av_options}")'
588
- - '[[ "${it_3_foxglove_bit_rate}" != "None" ]] && args+=(-p "ut.foxglove.bit_rate:=${it_3_foxglove_bit_rate}")'
589
- - '[[ "${it_3_foxglove_qmax}" != "None" ]] && args+=(-p "ut.foxglove.qmax:=${it_3_foxglove_qmax}")'
594
+ - 'if [[ "${it_3_transport}" != "None" ]]; then args+=(-p "out_transport:=${it_3_transport}"); fi'
595
+ - 'if [[ "${it_3_compressed_jpeg_quality}" != "None" ]]; then args+=(-p "ut.compressed.jpeg_quality:=${it_3_compressed_jpeg_quality}"); fi'
596
+ - 'if [[ "${it_3_ffmpeg_gop_size}" != "None" ]]; then args+=(-p "ut.ffmpeg.gop_size:=${it_3_ffmpeg_gop_size}"); fi'
597
+ - 'if [[ "${it_3_ffmpeg_encoder_av_options}" != "None" ]]; then args+=(-p "ut.ffmpeg.encoder_av_options:=${it_3_ffmpeg_encoder_av_options}"); fi'
598
+ - 'if [[ "${it_3_ffmpeg_bit_rate}" != "None" ]]; then args+=(-p "ut.ffmpeg.bit_rate:=${it_3_ffmpeg_bit_rate}"); fi'
599
+ - 'if [[ "${it_3_foxglove_gop_size}" != "None" ]]; then args+=(-p "ut.foxglove.gop_size:=${it_3_foxglove_gop_size}"); fi'
600
+ - 'if [[ "${it_3_foxglove_encoder_av_options}" != "None" ]]; then args+=(-p "ut.foxglove.encoder_av_options:=${it_3_foxglove_encoder_av_options}"); fi'
601
+ - 'if [[ "${it_3_foxglove_bit_rate}" != "None" ]]; then args+=(-p "ut.foxglove.bit_rate:=${it_3_foxglove_bit_rate}"); fi'
602
+ - 'if [[ "${it_3_foxglove_qmax}" != "None" ]]; then args+=(-p "ut.foxglove.qmax:=${it_3_foxglove_qmax}"); fi'
590
603
  - if [[ "${it_3_outgoing_suffix}" != "None" ]]; then outgoing_suffix="${it_3_outgoing_suffix}"; else outgoing_suffix="${it_3_transport}"; fi
591
604
  - if [[ "${it_in_transport}" == "raw" ]]; then in_remap="in"; else in_remap="in/${it_in_transport}"; fi
592
605
  - args+=(--remap "${in_remap}:=${it_3_topic}" --remap "out/${it_3_transport}:=${it_3_topic}/${outgoing_suffix}")
@@ -596,15 +609,15 @@ windows:
596
609
  - if [ '${it_4_topic}' = "None" ]; then exit; fi
597
610
  - if [[ "${it_4_topic}" == *"/compressed"* ]]; then it_in_transport="compressed"; else it_in_transport="raw"; fi
598
611
  - args=(ros2 run image_transport republish --ros-args -r __node:=republish4 -p in_transport:=${it_in_transport})
599
- - '[[ "${it_4_transport}" != "None" ]] && args+=(-p "out_transport:=${it_4_transport}")'
600
- - '[[ "${it_4_compressed_jpeg_quality}" != "None" ]] && args+=(-p "ut.compressed.jpeg_quality:=${it_4_compressed_jpeg_quality}")'
601
- - '[[ "${it_4_ffmpeg_gop_size}" != "None" ]] && args+=(-p "ut.ffmpeg.gop_size:=${it_4_ffmpeg_gop_size}")'
602
- - '[[ "${it_4_ffmpeg_encoder_av_options}" != "None" ]] && args+=(-p "ut.ffmpeg.encoder_av_options:=${it_4_ffmpeg_encoder_av_options}")'
603
- - '[[ "${it_4_ffmpeg_bit_rate}" != "None" ]] && args+=(-p "ut.ffmpeg.bit_rate:=${it_4_ffmpeg_bit_rate}")'
604
- - '[[ "${it_4_foxglove_gop_size}" != "None" ]] && args+=(-p "ut.foxglove.gop_size:=${it_4_foxglove_gop_size}")'
605
- - '[[ "${it_4_foxglove_encoder_av_options}" != "None" ]] && args+=(-p "ut.foxglove.encoder_av_options:=${it_4_foxglove_encoder_av_options}")'
606
- - '[[ "${it_4_foxglove_bit_rate}" != "None" ]] && args+=(-p "ut.foxglove.bit_rate:=${it_4_foxglove_bit_rate}")'
607
- - '[[ "${it_4_foxglove_qmax}" != "None" ]] && args+=(-p "ut.foxglove.qmax:=${it_4_foxglove_qmax}")'
612
+ - 'if [[ "${it_4_transport}" != "None" ]]; then args+=(-p "out_transport:=${it_4_transport}"); fi'
613
+ - 'if [[ "${it_4_compressed_jpeg_quality}" != "None" ]]; then args+=(-p "ut.compressed.jpeg_quality:=${it_4_compressed_jpeg_quality}"); fi'
614
+ - 'if [[ "${it_4_ffmpeg_gop_size}" != "None" ]]; then args+=(-p "ut.ffmpeg.gop_size:=${it_4_ffmpeg_gop_size}"); fi'
615
+ - 'if [[ "${it_4_ffmpeg_encoder_av_options}" != "None" ]]; then args+=(-p "ut.ffmpeg.encoder_av_options:=${it_4_ffmpeg_encoder_av_options}"); fi'
616
+ - 'if [[ "${it_4_ffmpeg_bit_rate}" != "None" ]]; then args+=(-p "ut.ffmpeg.bit_rate:=${it_4_ffmpeg_bit_rate}"); fi'
617
+ - 'if [[ "${it_4_foxglove_gop_size}" != "None" ]]; then args+=(-p "ut.foxglove.gop_size:=${it_4_foxglove_gop_size}"); fi'
618
+ - 'if [[ "${it_4_foxglove_encoder_av_options}" != "None" ]]; then args+=(-p "ut.foxglove.encoder_av_options:=${it_4_foxglove_encoder_av_options}"); fi'
619
+ - 'if [[ "${it_4_foxglove_bit_rate}" != "None" ]]; then args+=(-p "ut.foxglove.bit_rate:=${it_4_foxglove_bit_rate}"); fi'
620
+ - 'if [[ "${it_4_foxglove_qmax}" != "None" ]]; then args+=(-p "ut.foxglove.qmax:=${it_4_foxglove_qmax}"); fi'
608
621
  - if [[ "${it_4_outgoing_suffix}" != "None" ]]; then outgoing_suffix="${it_4_outgoing_suffix}"; else outgoing_suffix="${it_4_transport}"; fi
609
622
  - if [[ "${it_in_transport}" == "raw" ]]; then in_remap="in"; else in_remap="in/${it_in_transport}"; fi
610
623
  - args+=(--remap "${in_remap}:=${it_4_topic}" --remap "out/${it_4_transport}:=${it_4_topic}/${outgoing_suffix}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rosotacom-dev
3
- Version: 2.5.dev37
3
+ Version: 2.5.dev39
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -14,9 +14,7 @@ justfile
14
14
  pyproject.toml
15
15
  requirements.txt
16
16
  rosotacom.yaml
17
- run_session_in_container.py
18
17
  session-configuration.md
19
- stop_session_in_container.py
20
18
  terminology.md
21
19
  .devcontainer/devcontainer.json.template
22
20
  .devcontainer/re_generate_devcontainer_json.py
@@ -339,6 +337,8 @@ tests/unit/test_ota_unwrapper.py
339
337
  tests/unit/test_ota_wrapper.py
340
338
  tests/unit/test_ota_xml.py
341
339
  tests/unit/test_plots.py
340
+ tests/unit/test_qos_fallback_logging.py
341
+ tests/unit/test_relay_optional_parameters.py
342
342
  tests/unit/test_session_pipeline.py
343
343
  tests/unit/test_stage_latency.py
344
344
  tests/unit/test_status_eval.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ rosotacom = rosotacom.cli:main
@@ -87,7 +87,6 @@
87
87
  "pyproject.toml",
88
88
  "requirements.txt",
89
89
  "rosotacom.yaml",
90
- "run_session_in_container.py",
91
90
  "session-configuration.md",
92
91
  "src/rosotacom/__init__.py",
93
92
  "src/rosotacom/__main__.py",
@@ -281,7 +280,6 @@
281
280
  "src/rosotacom/trace_profiles.py",
282
281
  "src/rosotacom/transit.py",
283
282
  "src/rosotacom/video_quality.py",
284
- "stop_session_in_container.py",
285
283
  "terminology.md",
286
284
  "tests/contract/test_benched_set_registry.py",
287
285
  "tests/contract/test_findings.py",
@@ -334,6 +332,8 @@
334
332
  "tests/unit/test_ota_wrapper.py",
335
333
  "tests/unit/test_ota_xml.py",
336
334
  "tests/unit/test_plots.py",
335
+ "tests/unit/test_qos_fallback_logging.py",
336
+ "tests/unit/test_relay_optional_parameters.py",
337
337
  "tests/unit/test_session_pipeline.py",
338
338
  "tests/unit/test_stage_latency.py",
339
339
  "tests/unit/test_status_eval.py",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "tag": "2.4",
3
- "distance": 37,
4
- "node": "g14af11d921417944e98035154a1166f10ebd923c",
3
+ "distance": 39,
4
+ "node": "g17e7c753489cb153f8066e2911d37fdd85dcdb2f",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-08-14"
@@ -15,12 +15,20 @@ def test_package_version_is_derived_from_scm_metadata() -> None:
15
15
  assert '__version__ = "0.1.0"' not in package_init
16
16
 
17
17
 
18
- def test_console_scripts_target_package_cli() -> None:
18
+ def test_rosotacom_is_the_only_console_script() -> None:
19
+ """One installed command, so a shim in ~/.local/bin cannot be mistaken for it.
20
+
21
+ `start_rosotacom` / `stop_rosotacom` were removed on 2026-08-14: they were
22
+ `rosotacom start` / `rosotacom stop` under a second name (see
23
+ DEVELOPMENT_PRINCIPLES.md, Compatibility Policy). This pins that no second
24
+ name comes back.
25
+ """
19
26
  pyproject = (PACKAGE_ROOT / "pyproject.toml").read_text(encoding="utf-8")
27
+ scripts = pyproject.split("[project.scripts]", 1)[1].split("\n[", 1)[0]
28
+ entries = [line.split("=", 1)[0].strip() for line in scripts.splitlines() if "=" in line]
20
29
 
21
30
  assert 'rosotacom = "rosotacom.cli:main"' in pyproject
22
- assert 'start_rosotacom = "rosotacom.cli:start_compat_main"' in pyproject
23
- assert 'stop_rosotacom = "rosotacom.cli:stop_compat_main"' in pyproject
31
+ assert entries == ["rosotacom"], entries
24
32
 
25
33
 
26
34
  def test_videoquality_reader_dependencies_are_packaged() -> None:
@@ -111,3 +111,77 @@ def test_the_hook_is_installed_once_even_if_sourced_twice(pane_env: tuple[Path,
111
111
 
112
112
  (line,) = [ln for ln in result.stdout.splitlines() if ln.startswith("PC=")]
113
113
  assert line.count("__rosotacom_note_exit") == 1
114
+
115
+
116
+ # What the recorder cannot know, and why the session template has to care.
117
+ #
118
+ # The hook runs from PROMPT_COMMAND, so it sees every line a pane shell runs --
119
+ # including the lines that only assemble an argument list before the node
120
+ # starts. A line of the form `[[ cond ]] && args+=(...)` exits 1 whenever the
121
+ # condition is false, which is the normal case for every option a session leaves
122
+ # unset, so each one recorded itself as a dead pane. A peer then reported four
123
+ # exited panes at every start while nothing was wrong.
124
+
125
+ _UNSET_OPTION = '[[ "None" != "None" ]]'
126
+ _SET_OPTION = '[[ "22" != "None" ]]'
127
+
128
+
129
+ def _failure_log(catmux_dir: Path) -> Path:
130
+ return catmux_dir.parent / "pane_failures.log"
131
+
132
+
133
+ def test_the_short_circuit_form_records_a_false_failure(pane_env: tuple[Path, dict[str, str]]) -> None:
134
+ """The shape that was in the template: correct behaviour, status 1."""
135
+ catmux_dir, env = pane_env
136
+
137
+ _run(f'args=(); {_UNSET_OPTION} && args+=(-p "bit_rate:=None")', env)
138
+
139
+ assert _failure_log(catmux_dir).is_file()
140
+ assert "exit=1" in _failure_log(catmux_dir).read_text(encoding="utf-8")
141
+
142
+
143
+ def test_the_if_form_leaves_an_unset_option_silent(pane_env: tuple[Path, dict[str, str]]) -> None:
144
+ """The shape it was replaced with: same behaviour, status 0."""
145
+ catmux_dir, env = pane_env
146
+
147
+ _run(f'args=(); if {_UNSET_OPTION}; then args+=(-p "bit_rate:=None"); fi', env)
148
+
149
+ assert not _failure_log(catmux_dir).exists()
150
+
151
+
152
+ def test_the_if_form_still_appends_a_set_option(pane_env: tuple[Path, dict[str, str]]) -> None:
153
+ """Silencing the status must not silence the argument."""
154
+ catmux_dir, env = pane_env
155
+
156
+ result = _run(
157
+ f'args=(); if {_SET_OPTION}; then args+=(-p "bit_rate:=22"); fi\necho "ARGS=${{args[*]}}"',
158
+ env,
159
+ )
160
+
161
+ assert "ARGS=-p bit_rate:=22" in result.stdout
162
+ assert not _failure_log(catmux_dir).exists()
163
+
164
+
165
+ def test_no_session_template_line_uses_the_short_circuit_form() -> None:
166
+ """The template is where this reaches a running session, so it is checked there."""
167
+ template = (
168
+ REPO_ROOT
169
+ / "src"
170
+ / "rosotacom"
171
+ / "resources"
172
+ / "ws"
173
+ / "session"
174
+ / "content"
175
+ / "base"
176
+ / "session_plugin_base.yaml"
177
+ )
178
+ offenders = [
179
+ line.strip()
180
+ for line in template.read_text(encoding="utf-8").splitlines()
181
+ if line.lstrip().startswith("- '[[") and "&&" in line
182
+ ]
183
+
184
+ assert offenders == [], (
185
+ "these lines exit non-zero when their option is unset and land in "
186
+ f"pane_failures.log; use `if ...; then ...; fi`: {offenders}"
187
+ )
@@ -1990,20 +1990,14 @@ rosbag2_bagfile_information:
1990
1990
  assert "TEST OK" in capsys.readouterr().out
1991
1991
 
1992
1992
 
1993
- def test_start_and_stop_compat_entrypoints_prefix_commands(monkeypatch: pytest.MonkeyPatch) -> None:
1994
- calls: list[list[str]] = []
1995
-
1996
- def fake_main(argv: list[str] | None = None) -> int:
1997
- calls.append(list(argv or []))
1998
- return 0
1993
+ def test_the_retired_compat_entrypoints_are_gone() -> None:
1994
+ """Removed on 2026-08-14 — they were `start`/`stop` under a second name.
1999
1995
 
2000
- monkeypatch.setattr(rosotacom, "main", fake_main)
2001
- monkeypatch.setattr(sys, "argv", ["start_rosotacom", "1_heartbeat"])
2002
- assert rosotacom.start_compat_main() == 0
2003
- monkeypatch.setattr(sys, "argv", ["stop_rosotacom", "1_heartbeat"])
2004
- assert rosotacom.stop_compat_main() == 0
2005
-
2006
- assert calls == [["start", "1_heartbeat"], ["stop", "1_heartbeat"]]
1996
+ Asserting their absence is the point: a re-added alias would otherwise pass
1997
+ every other test in this file silently.
1998
+ """
1999
+ assert not hasattr(rosotacom, "start_compat_main")
2000
+ assert not hasattr(rosotacom, "stop_compat_main")
2007
2001
 
2008
2002
 
2009
2003
  def test_path_yaml_and_network_helpers(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: