rosotacom-dev 2.5.dev27__tar.gz → 2.5.dev33__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 (347) hide show
  1. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/workflows/nightly-e2e.yml +23 -5
  2. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/workflows/pr-merge-gate.yml +31 -14
  3. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/workflows/release.yml +19 -2
  4. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/PKG-INFO +1 -1
  5. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/ci.md +39 -31
  6. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/testing.md +14 -9
  7. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/justfile +1 -1
  8. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/session-configuration.md +23 -7
  9. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/cli.py +17 -2
  10. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/image_cache.py +5 -5
  11. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/ros2docker.json +13 -5
  12. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +11 -0
  13. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ros2docker.json.example +13 -5
  14. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +20 -5
  15. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +27 -0
  16. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +7 -1
  17. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +70 -33
  18. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom_dev.egg-info/PKG-INFO +1 -1
  19. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom_dev.egg-info/SOURCES.txt +3 -0
  20. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom_dev.egg-info/scm_file_list.json +3 -0
  21. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
  22. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_benched_set_registry.py +3 -2
  23. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_packaged_resources.py +56 -0
  24. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_security_maintenance_config.py +10 -6
  25. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_workflow_contracts.py +15 -16
  26. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/e2e/conftest.py +25 -12
  27. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_cli.py +42 -0
  28. rosotacom_dev-2.5.dev33/tests/unit/test_ota_wrapper.py +170 -0
  29. rosotacom_dev-2.5.dev33/tests/unit/test_session_pipeline.py +196 -0
  30. rosotacom_dev-2.5.dev33/tests/unit/test_status_overview_observer.py +225 -0
  31. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.devcontainer/devcontainer.json.template +0 -0
  32. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.devcontainer/re_generate_devcontainer_json.py +0 -0
  33. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/CODEOWNERS +0 -0
  34. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
  35. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
  36. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
  37. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
  38. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
  39. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
  40. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
  41. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
  42. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  43. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/actions/setup-just/action.yml +0 -0
  44. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/dependabot.yml +0 -0
  45. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/workflows/benchmark-calibrate.yml +0 -0
  46. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/workflows/benchmark-gate.yml +0 -0
  47. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/workflows/dev-release.yml +0 -0
  48. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/workflows/image-scan.yml +0 -0
  49. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.github/workflows/pr-lightweight.yml +0 -0
  50. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/.pre-commit-config.yaml +0 -0
  51. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/AGENTS.md +0 -0
  52. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/CONCURRENCY.md +0 -0
  53. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/CONTRIBUTING.md +0 -0
  54. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/DEVELOPMENT_PRINCIPLES.md +0 -0
  55. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/LICENSE.txt +0 -0
  56. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/MANIFEST.in +0 -0
  57. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/README.md +0 -0
  58. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/budgets.jsonl +0 -0
  59. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/calibration/README.md +0 -0
  60. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/calibration/capacity-size-tight-cyclone.json +0 -0
  61. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
  62. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/calibration/probe-loss-nominal-cyclone.json +0 -0
  63. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/calibration/probe-loss-tight-cyclone.json +0 -0
  64. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/calibration/probe-loss-tight-fastdds.json +0 -0
  65. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/calibration/probe-loss-tight-zenoh.json +0 -0
  66. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/codecov.yml +0 -0
  67. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/deployment-configuration.md +0 -0
  68. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/benchmark-ab.md +0 -0
  69. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/benchmark-bag-as-load.md +0 -0
  70. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/ffmpeg-keyframes.md +0 -0
  71. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/findings/README.md +0 -0
  72. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
  73. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/findings/delay-alone-no-loss.md +0 -0
  74. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/findings/head-of-line-irregularity.md +0 -0
  75. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
  76. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/findings/lighter-message-loss.md +0 -0
  77. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
  78. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/forensics-report.md +0 -0
  79. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/geo-link-map.md +0 -0
  80. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/github-repository-settings.md +0 -0
  81. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/link-trace.md +0 -0
  82. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/owner-runbook.md +0 -0
  83. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/performance-bands.md +0 -0
  84. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/playbooks/README.md +0 -0
  85. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/quality-model.md +0 -0
  86. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/release-notes/TEMPLATE.md +0 -0
  87. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/release-notes/v2.1.md +0 -0
  88. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/release-notes/v2.2.md +0 -0
  89. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/release-notes/v2.3.md +0 -0
  90. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/release-notes/v2.4.md +0 -0
  91. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/release.md +0 -0
  92. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
  93. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/rfcs/0002-expectation-concepts.md +0 -0
  94. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/rfcs/0003-metric-backbone.md +0 -0
  95. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/rfcs/0004-network-profiles.md +0 -0
  96. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
  97. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/rfcs/0006-dynamic-qos.md +0 -0
  98. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/rfcs/0007-regression-gate.md +0 -0
  99. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/rfcs/README.md +0 -0
  100. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/docs/work-items.md +0 -0
  101. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/install.sh +0 -0
  102. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/media/control_center.png +0 -0
  103. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/media/echo_test.png +0 -0
  104. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/media/forensics-report-example.png +0 -0
  105. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/media/host.png +0 -0
  106. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/media/vehicle.png +0 -0
  107. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/pyproject.toml +0 -0
  108. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/requirements.txt +0 -0
  109. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/rosotacom.yaml +0 -0
  110. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/run_session_in_container.py +0 -0
  111. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/setup.cfg +0 -0
  112. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/__init__.py +0 -0
  113. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/__main__.py +0 -0
  114. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/anonymize.py +0 -0
  115. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/bag_ground_truth.py +0 -0
  116. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/benched_set.py +0 -0
  117. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/benchmark.py +0 -0
  118. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/benchmark_delta.py +0 -0
  119. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/bundle_check.py +0 -0
  120. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/cli_benchmark.py +0 -0
  121. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/deployment.py +0 -0
  122. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/ffmpeg_packet.py +0 -0
  123. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/forensics.py +0 -0
  124. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/geomap.py +0 -0
  125. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/network_profiles.py +0 -0
  126. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/network_shaper.py +0 -0
  127. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/plots.py +0 -0
  128. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/py.typed +0 -0
  129. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/benched-set.yaml +0 -0
  130. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/.gitignore +0 -0
  131. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/README.md +0 -0
  132. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/__init__.py +0 -0
  133. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
  134. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
  135. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/profiles.yaml +0 -0
  136. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
  137. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
  138. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
  139. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
  140. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
  141. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
  142. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
  143. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
  144. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
  145. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
  146. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
  147. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
  148. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
  149. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
  150. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
  151. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
  152. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  153. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
  154. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
  155. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
  156. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
  157. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
  158. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
  159. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
  160. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
  161. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
  162. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  163. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
  164. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
  165. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
  166. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
  167. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
  168. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
  169. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
  170. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
  171. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
  172. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
  173. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
  174. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
  175. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
  176. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
  177. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
  178. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
  179. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
  180. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
  181. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
  182. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
  183. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
  184. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
  185. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
  186. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
  187. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
  188. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
  189. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
  190. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
  191. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
  192. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
  193. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
  194. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
  195. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
  196. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
  197. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
  198. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
  199. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
  200. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
  201. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
  202. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
  203. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
  204. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
  205. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
  206. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
  207. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
  208. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
  209. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
  210. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
  211. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
  212. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
  213. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
  214. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
  215. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
  216. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
  217. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
  218. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
  219. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
  220. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
  221. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
  222. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
  223. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
  224. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
  225. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
  226. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
  227. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
  228. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
  229. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
  230. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
  231. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
  232. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
  233. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
  234. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
  235. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
  236. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
  237. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
  238. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
  239. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
  240. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
  241. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
  242. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
  243. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
  244. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
  245. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
  246. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
  247. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
  248. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
  249. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
  250. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
  251. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
  252. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
  253. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
  254. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
  255. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
  256. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
  257. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
  258. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
  259. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
  260. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
  261. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
  262. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
  263. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
  264. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
  265. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
  266. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
  267. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
  268. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
  269. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
  270. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
  271. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
  272. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
  273. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
  274. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
  275. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
  276. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
  277. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
  278. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
  279. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
  280. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +0 -0
  281. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
  282. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
  283. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
  284. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
  285. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
  286. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
  287. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
  288. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
  289. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/status_eval.py +0 -0
  290. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/stream_stats.py +0 -0
  291. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/trace_profiles.py +0 -0
  292. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/transit.py +0 -0
  293. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom/video_quality.py +0 -0
  294. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
  295. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
  296. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom_dev.egg-info/requires.txt +0 -0
  297. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
  298. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/stop_session_in_container.py +0 -0
  299. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/terminology.md +0 -0
  300. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_findings.py +0 -0
  301. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_markdown_links.py +0 -0
  302. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_ota_source_bundle.py +0 -0
  303. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_package_metadata.py +0 -0
  304. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_profile_covers_generated_commands.py +0 -0
  305. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_pytest_policy.py +0 -0
  306. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_readme_examples.py +0 -0
  307. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/contract/test_session_configuration_doc.py +0 -0
  308. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/e2e/test_anonymize_e2e.py +0 -0
  309. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/e2e/test_benchmark_ab.py +0 -0
  310. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/e2e/test_benchmark_capacity.py +0 -0
  311. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/e2e/test_benchmark_replay.py +0 -0
  312. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/e2e/test_parallel_smoke.py +0 -0
  313. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/e2e/test_smoke.py +0 -0
  314. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/e2e/test_timeline_stepping.py +0 -0
  315. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/e2e/test_video_quality_e2e.py +0 -0
  316. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/sessions/generate_rmw_matrix.py +0 -0
  317. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
  318. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
  319. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
  320. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
  321. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
  322. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_anonymize.py +0 -0
  323. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_bag_ground_truth.py +0 -0
  324. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_benched_set.py +0 -0
  325. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_benchmark.py +0 -0
  326. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_benchmark_delta.py +0 -0
  327. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_bundle_check.py +0 -0
  328. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_cli_benchmark.py +0 -0
  329. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_concurrency.py +0 -0
  330. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_deployment.py +0 -0
  331. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_ffmpeg_packet.py +0 -0
  332. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_forensics.py +0 -0
  333. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_geomap.py +0 -0
  334. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_image_cache.py +0 -0
  335. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_link_bytes.py +0 -0
  336. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_link_trace.py +0 -0
  337. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_network_profiles.py +0 -0
  338. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_network_shaper.py +0 -0
  339. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_ota_xml.py +0 -0
  340. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_plots.py +0 -0
  341. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_stage_latency.py +0 -0
  342. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_status_eval.py +0 -0
  343. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_status_overview.py +0 -0
  344. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_stream_stats.py +0 -0
  345. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_trace_profiles.py +0 -0
  346. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_transit.py +0 -0
  347. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev33}/tests/unit/test_video_quality.py +0 -0
@@ -19,25 +19,43 @@ concurrency:
19
19
 
20
20
  jobs:
21
21
  smoke-e2e:
22
- # The same six slices the merge gate and the release run, instead of one
22
+ # The same diagnostic slices the merge gate and the release run, instead of one
23
23
  # sequential `just test-e2e-smoke` over the whole suite (#198). Keeping the
24
24
  # monolith here was deliberate while the slices were hand-maintained `-k`
25
25
  # expressions that had silently stopped covering three files; #197's
26
26
  # test_e2e_slices_partition_the_whole_suite closed that, so the union is
27
27
  # now guaranteed to be the monolith.
28
28
  #
29
- # The gain is diagnosis: a red monolith says "e2e broke", six slices say
30
- # which area did. It also removes a load-induced flake. On 2026-08-11 the
29
+ # The gain is diagnosis: a red monolith says "e2e broke"; a named slice says
30
+ # which area and, where relevant, which transport or behavior failed. It
31
+ # also removes a load-induced flake. On 2026-08-11 the
31
32
  # nightly failed with nine "Timed out waiting for container readiness"
32
33
  # errors after 1h12m on one runner, while the same tests on the same commit
33
- # passed in the merge gate — where they are spread over six.
34
+ # passed in the merge gate — where they were spread over six at the time.
34
35
  name: smoke-e2e-${{ matrix.slice }}
35
36
  runs-on: ubuntu-latest
36
37
  timeout-minutes: 90
37
38
  strategy:
38
39
  fail-fast: false
39
40
  matrix:
40
- slice: [heartbeat, chatter, occupancy-grid, sized-payload, remote-assist, remote-assist-streams, runtime-tools, media, concurrency, benchmark-ab, benchmark-replay, benchmark-capacity, benchmark-capacity-cases]
41
+ slice:
42
+ - heartbeat
43
+ - chatter
44
+ - occupancy-grid-dds
45
+ - occupancy-grid-zenoh
46
+ - sized-payload-fastdds
47
+ - sized-payload-zenoh
48
+ - remote-assist
49
+ - remote-assist-costmap
50
+ - remote-assist-camera
51
+ - runtime-tools
52
+ - media
53
+ - concurrency-parallel
54
+ - concurrency-conflict
55
+ - benchmark-ab
56
+ - benchmark-replay
57
+ - benchmark-capacity
58
+ - benchmark-capacity-cases
41
59
 
42
60
  steps:
43
61
  - name: Check out repository
@@ -159,7 +159,7 @@ jobs:
159
159
  quick-gate:
160
160
  # Everything `e2e` waits for that is not the image, and deliberately no
161
161
  # more. It exists to answer one question — is the tree obviously broken,
162
- # such that thirteen slices would burn seventy runner-minutes to say so.
162
+ # such that seventeen slices would burn roughly 73 runner-minutes to say so.
163
163
  #
164
164
  # It replaced a `needs: preflight-success` edge that made e2e wait for the
165
165
  # whole five-version matrix. That barrier cost 2.15 min of every gate run
@@ -199,12 +199,12 @@ jobs:
199
199
 
200
200
  image:
201
201
  # Publish the images the e2e suite builds, once per set of build inputs,
202
- # instead of rebuilding them in each of thirteen jobs. #236 measured that
203
- # build at 154s per job: 57s pulling the multi-GB ROS base from Docker Hub,
204
- # 40s exporting layers, 47s of apt and pip. A pull from GHCR — co-located
205
- # with the runners, no Hub rate limit, one transfer instead of a transfer
206
- # plus a build — replaces all of it, and takes twelve of the thirteen Hub
207
- # pulls off the merge gate's critical path.
202
+ # instead of rebuilding them in every job. #236 measured that build at
203
+ # 154s per job when the matrix had thirteen jobs: 57s pulling the multi-GB
204
+ # ROS base from Docker Hub, 40s exporting layers, 47s of apt and pip. A pull
205
+ # from GHCR — co-located with the runners, no Hub rate limit, one transfer
206
+ # instead of a transfer plus a build — replaces all of it. The benefit
207
+ # grows with the diagnostic matrix; seventeen jobs still build only once.
208
208
  #
209
209
  # The tag is a hash of everything that decides the image (base digest,
210
210
  # package lists, Dockerfile, entrypoint, ros2docker version, build UID):
@@ -295,12 +295,12 @@ jobs:
295
295
  # tests/contract/test_workflow_contracts.py keeps the three workflows and
296
296
  # the justfile agreeing.
297
297
  #
298
- # The slices are chosen by measured cost, not grouped by theme (#226):
299
- # themed slices spanned 7m39s to 18m31s, and one test ran in two of them.
300
- # Thirteen rather than six because the model that predicted the balanced
301
- # six within 25s also says twelve reaches the floor and more buys nothing
302
- # (#235). Which tests a slice owns and what each costs is E2E_SLICES in
303
- # tests/e2e/conftest.py — change that, not this line, to move a test.
298
+ # Slice names are diagnostic boundaries, not cost buckets. Costs tell us
299
+ # when a theme needs another runner; they never justify packing unrelated
300
+ # tests together. Seventeen is the smallest theme-preserving partition that
301
+ # reaches the measured floor: #253 split the four overloaded themes along
302
+ # transport, stream, or concurrency semantics. Which tests a slice owns and
303
+ # what each costs is E2E_SLICES in tests/e2e/conftest.py.
304
304
  name: e2e-${{ matrix.slice }}
305
305
  runs-on: ubuntu-latest
306
306
  timeout-minutes: 90
@@ -312,7 +312,24 @@ jobs:
312
312
  strategy:
313
313
  fail-fast: false
314
314
  matrix:
315
- slice: [heartbeat, chatter, occupancy-grid, sized-payload, remote-assist, remote-assist-streams, runtime-tools, media, concurrency, benchmark-ab, benchmark-replay, benchmark-capacity, benchmark-capacity-cases]
315
+ slice:
316
+ - heartbeat
317
+ - chatter
318
+ - occupancy-grid-dds
319
+ - occupancy-grid-zenoh
320
+ - sized-payload-fastdds
321
+ - sized-payload-zenoh
322
+ - remote-assist
323
+ - remote-assist-costmap
324
+ - remote-assist-camera
325
+ - runtime-tools
326
+ - media
327
+ - concurrency-parallel
328
+ - concurrency-conflict
329
+ - benchmark-ab
330
+ - benchmark-replay
331
+ - benchmark-capacity
332
+ - benchmark-capacity-cases
316
333
 
317
334
  steps:
318
335
  - name: Check out repository
@@ -110,7 +110,7 @@ jobs:
110
110
  retention-days: 30
111
111
 
112
112
  e2e:
113
- # The same five slices the merge gate runs, in parallel, instead of one
113
+ # The same diagnostic slices the merge gate runs, in parallel, instead of one
114
114
  # sequential `just test-e2e-smoke` over the whole suite. That target is
115
115
  # identical to nightly-e2e.yml's smoke-e2e job, so the release used to be
116
116
  # the third sequential run of the same tests against the same tree; it
@@ -121,7 +121,24 @@ jobs:
121
121
  strategy:
122
122
  fail-fast: false
123
123
  matrix:
124
- slice: [heartbeat, chatter, occupancy-grid, sized-payload, remote-assist, remote-assist-streams, runtime-tools, media, concurrency, benchmark-ab, benchmark-replay, benchmark-capacity, benchmark-capacity-cases]
124
+ slice:
125
+ - heartbeat
126
+ - chatter
127
+ - occupancy-grid-dds
128
+ - occupancy-grid-zenoh
129
+ - sized-payload-fastdds
130
+ - sized-payload-zenoh
131
+ - remote-assist
132
+ - remote-assist-costmap
133
+ - remote-assist-camera
134
+ - runtime-tools
135
+ - media
136
+ - concurrency-parallel
137
+ - concurrency-conflict
138
+ - benchmark-ab
139
+ - benchmark-replay
140
+ - benchmark-capacity
141
+ - benchmark-capacity-cases
125
142
 
126
143
  steps:
127
144
  - name: Check out repository
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rosotacom-dev
3
- Version: 2.5.dev27
3
+ Version: 2.5.dev33
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -43,23 +43,22 @@ check is:
43
43
  ci-success
44
44
  ```
45
45
 
46
- The merge gate runs workflow lint, dependency/security review, runtime/build asset lint, Python 3.10 through 3.14 non-Docker checks, package validation, and the Docker single-machine smoke matrix (one matrix job per slice, thirteen in parallel):
46
+ The merge gate runs workflow lint, dependency/security review, runtime/build asset lint, Python 3.10 through 3.14 non-Docker checks, package validation, and the Docker single-machine smoke matrix (one matrix job per slice, seventeen in parallel):
47
47
 
48
48
  Python 3.10–3.14 are supported for the host CLI; Python 3.12 is the reference
49
49
  interpreter for packaging and Docker E2E jobs.
50
50
 
51
51
  ### What the e2e slices wait for
52
52
 
53
- Every job in the gate starts at once there is no runner contention — so the
54
- only thing that decides when the thirteen slices start is their `needs`. They
53
+ The only explicit barriers before the seventeen slices are their `needs`. They
55
54
  wait for exactly two jobs:
56
55
 
57
56
  - **`image`**, because a slice adopts the published image rather than building
58
57
  it, so it cannot start before that image is known to exist. On a hit this is
59
58
  two manifest inspections, and it is what sets the floor.
60
59
  - **`quick-gate`**, `just lint && just typecheck` on one interpreter: the
61
- cheapest signal that the tree is not obviously broken, so thirteen runners do
62
- not spend seventy minutes discovering a syntax error. Four seconds of work,
60
+ cheapest signal that the tree is not obviously broken, so seventeen runners
61
+ do not spend roughly 73 minutes discovering a syntax error. Four seconds of work,
63
62
  sized to finish inside `image` and therefore free.
64
63
 
65
64
  They used to wait for `preflight-success`, which meant the whole five-version
@@ -84,13 +83,17 @@ just package
84
83
  # Parallel E2E lanes, one per slice:
85
84
  just test-e2e-slice heartbeat
86
85
  just test-e2e-slice chatter
87
- just test-e2e-slice occupancy-grid
88
- just test-e2e-slice sized-payload
86
+ just test-e2e-slice occupancy-grid-dds
87
+ just test-e2e-slice occupancy-grid-zenoh
88
+ just test-e2e-slice sized-payload-fastdds
89
+ just test-e2e-slice sized-payload-zenoh
89
90
  just test-e2e-slice remote-assist
90
- just test-e2e-slice remote-assist-streams
91
+ just test-e2e-slice remote-assist-costmap
92
+ just test-e2e-slice remote-assist-camera
91
93
  just test-e2e-slice runtime-tools
92
94
  just test-e2e-slice media
93
- just test-e2e-slice concurrency
95
+ just test-e2e-slice concurrency-parallel
96
+ just test-e2e-slice concurrency-conflict
94
97
  just test-e2e-slice benchmark-ab
95
98
  just test-e2e-slice benchmark-replay
96
99
  just test-e2e-slice benchmark-capacity
@@ -102,7 +105,7 @@ Docker E2E is not collected for coverage.
102
105
 
103
106
  ## Docker E2E
104
107
 
105
- `just test-e2e-smoke` runs the entire local single-machine smoke matrix through Docker. In the CI merge gate, the same collection runs as thirteen parallel
108
+ `just test-e2e-smoke` runs the entire local single-machine smoke matrix through Docker. In the CI merge gate, the same collection runs as seventeen parallel
106
109
  jobs, one per slice, named `e2e-<slice>`. Each smoke run writes generated
107
110
  config, catmux pane logs, Docker logs when available, and the smoke verification
108
111
  log under `session-instances/`; collect that directory as the first debugging
@@ -112,8 +115,9 @@ artifact when an E2E job fails.
112
115
 
113
116
  Every e2e job used to build the project image from scratch. #236 measured that
114
117
  at 154s per job — 57s pulling the multi-GB ROS base from Docker Hub, 40s
115
- exporting layers, 47s of apt and pip — which at thirteen slices is 33 minutes of
116
- runner time and thirteen Hub pulls on the critical path of every merge gate.
118
+ exporting layers, 47s of apt and pip — which was 33 minutes of runner time and
119
+ thirteen Hub pulls with the matrix at that time. The image is still published
120
+ only once now that the diagnostic matrix has seventeen jobs.
117
121
 
118
122
  The `image` job now publishes those images to
119
123
  `ghcr.io/<owner>/rosotacom-e2e` and each slice pulls instead of building. GHCR
@@ -165,14 +169,13 @@ Content-addressed tags accumulate in the GHCR package — one per distinct set o
165
169
  build inputs, so roughly one per change to the base digest or package lists.
166
170
  Nothing prunes them yet.
167
171
 
168
- ### Balancing the e2e slices
172
+ ### Diagnostic e2e slices
169
173
 
170
174
  A slice is not its own pytest invocation. `just test-e2e-slice <name>` runs the
171
175
  monolith's collection with `--e2e-slice=<name>`, and everything the named slice
172
176
  does not own is deselected. Which tests a slice owns, and what each one costs,
173
177
  is `E2E_SLICES` in `tests/e2e/conftest.py`; `just e2e-slice-costs` prints the
174
- resulting balance. Moving a test between slices is one line there — the
175
- workflow matrices only name slices.
178
+ resulting costs. The workflow matrices only name slices.
176
179
 
177
180
  That shape exists because the previous one, per-slice file lists and `-k`
178
181
  filters, could not say what it ran. `-k "remote_assist"` silently missed the
@@ -182,11 +185,17 @@ twice a run. A partition can do neither: an unowned test fails every slice job
182
185
  with a usage error, and a test owned twice fails
183
186
  `test_e2e_slices_partition_the_whole_suite`.
184
187
 
188
+ The slice name is an advisor: it states the subsystem and, where that is the
189
+ useful first distinction, the transport, stream, or behavior that failed.
190
+ Costs decide when one such theme needs another runner. They do not justify
191
+ moving a test behind an unrelated name just because its duration fits there.
192
+
185
193
  The costs are warm pytest `call` durations — medians over seven merge-gate runs
186
194
  of 2026-08-11/12. On top of them each job pays a fixed
187
195
  `RUNNER_SETUP_SECONDS + IMAGE_BUILD_SECONDS` (1m19s: 46s outside the tests, then
188
196
  the project image obtained inside whichever test runs first). Because that
189
- constant is per job and not per test, balancing warm costs balances wall clock.
197
+ constant is per job and not per test, the cost model predicts wall clock and
198
+ shows when a diagnostic group has become too large.
190
199
 
191
200
  `IMAGE_BUILD_SECONDS` models the merge gate, where that image is pulled rather
192
201
  than built (see above); the release and nightly lanes still build and pay the
@@ -206,26 +215,25 @@ cost like every other. It is currently **5m47s**, of which 33s is the image
206
215
  (7m56s before #236 published it instead of rebuilding it per job, 6m32s before
207
216
  #245 shrank it).
208
217
 
209
- Thirteen slices sit at 6m26s, **1.12x** the floor. That is the point of choosing
210
- N from the numbers rather than from taste: six balanced slices were 13m37s,
211
- twelve reach the floor, and past twelve every extra job is pure cost. Note that
212
- 1.12x is now a partition problem rather than a count problem — thirteen slices
213
- *can* reach 1.00x, and the current assignment does not, because `occupancy-grid`
214
- holds two 150s tests. The fixed cost falling twice is what exposed it: the same
215
- partition was 1.11x of a floor that was a minute and a half higher. The
216
- contract test asserts distance to the floor rather than the spread between
217
- slices spread is compressed toward 1.0 by the fixed cost as N grows, so it
218
- keeps reading fine while the gate stops improving.
219
-
220
- Runner minutes are not the constraint here (this repository is public, so
221
- standard GitHub-hosted runners are free); the concurrent-job cap is, and
222
- thirteen stays under it.
218
+ Thirteen diagnostic slices sat at 6m26s, **1.12x** the floor. Four groups were
219
+ over the 267s warm target: occupancy grid, sized payload, the two remote-assist
220
+ single-stream cuts, and the two concurrency guarantees. Each has a real seam
221
+ transport, stream, or behavior so each became two explicitly named jobs.
222
+
223
+ The resulting seventeen slices reach **1.00x**, without cross-theme packing.
224
+ Seventeen is also the smallest theme-preserving count that can do so: each of
225
+ the four overloaded groups needs at least one additional runner. Splitting
226
+ every test into its own job would add runner cost without improving the critical
227
+ path; keeping thirteen would save runner setup but leave 42s on every gate run.
228
+ This is the balance: use the fewest runners that preserve diagnostic ownership
229
+ and reach the floor, rather than optimizing either runner count or time alone.
223
230
 
224
231
  To refresh the numbers, read a merge-gate run: every e2e invocation runs
225
232
  `--durations=0`, so each job prints the cost of every test it ran. A test that
226
233
  ran first in its job carries the image build and needs `IMAGE_BUILD_SECONDS`
227
234
  subtracted. `tests/contract/test_workflow_contracts.py::test_e2e_slices_stay_close_to_the_floor`
228
- fails when the slowest slice passes 1.25x the floor.
235
+ fails as soon as a grouped slice becomes slower than the floor. Split that
236
+ slice on a diagnostic boundary; do not fill spare time with unrelated tests.
229
237
 
230
238
  ## Performance Regression Gate
231
239
 
@@ -127,24 +127,29 @@ from one-host smoke.
127
127
 
128
128
  - `just test-e2e-slice heartbeat`: the heartbeat matrix (and the opt-in RMW matrix).
129
129
  - `just test-e2e-slice chatter`: the native chatter scenario, smoke, and debug rig.
130
- - `just test-e2e-slice occupancy-grid`: compressed occupancy grid over both transports.
131
- - `just test-e2e-slice sized-payload`: sized payload over both transports.
130
+ - `just test-e2e-slice occupancy-grid-dds`: compressed occupancy grid over direct DDS.
131
+ - `just test-e2e-slice occupancy-grid-zenoh`: compressed occupancy grid over Zenoh.
132
+ - `just test-e2e-slice sized-payload-fastdds`: sized payload over Fast DDS.
133
+ - `just test-e2e-slice sized-payload-zenoh`: sized payload over Zenoh.
132
134
  - `just test-e2e-slice remote-assist`: the full anonymized remote-assist rig.
133
- - `just test-e2e-slice remote-assist-streams`: its costmap and camera single-stream cuts.
135
+ - `just test-e2e-slice remote-assist-costmap`: its costmap single-stream cut.
136
+ - `just test-e2e-slice remote-assist-camera`: its camera single-stream cut.
134
137
  - `just test-e2e-slice runtime-tools`: link latency and live timeline stepping.
135
138
  - `just test-e2e-slice media`: anonymization and video quality.
136
- - `just test-e2e-slice concurrency`: the concurrency/isolation gate.
139
+ - `just test-e2e-slice concurrency-parallel`: independent smoke runs coexist.
140
+ - `just test-e2e-slice concurrency-conflict`: a conflicting smoke run is rejected safely.
137
141
  - `just test-e2e-slice benchmark-ab`: the A/B reliability verdict.
138
142
  - `just test-e2e-slice benchmark-replay`: loss boundaries against costmap replay.
139
143
  - `just test-e2e-slice benchmark-capacity`: the band-asserted capacity rows.
140
144
  - `just test-e2e-slice benchmark-capacity-cases`: the capacity good/bad-case verdicts.
141
145
  - `just test-e2e-node <nodeid>`: Reruns a specific pytest node ID directly.
142
- - `just e2e-slice-costs`: prints what each slice costs and how balanced the six are.
146
+ - `just e2e-slice-costs`: prints what each slice costs and its distance to the floor.
143
147
 
144
- The slices are chosen by measured cost, and split where the tests already
145
- differ so a red job names an area. `E2E_SLICES` in `tests/e2e/conftest.py`
146
- decides which slice owns which test; see
147
- [ci.md](ci.md#balancing-the-e2e-slices) before moving one.
148
+ The slices are grouped by diagnostic theme and split where transport, stream,
149
+ or behavior gives a useful first failure distinction. Measured cost decides
150
+ when a theme needs another runner, not which unrelated tests should share one.
151
+ `E2E_SLICES` in `tests/e2e/conftest.py` decides which slice owns which test;
152
+ see [ci.md](ci.md#diagnostic-e2e-slices) before changing one.
148
153
 
149
154
  The generated RMW matrix is available as an opt-in full local slice:
150
155
 
@@ -46,7 +46,7 @@ test-e2e-fast: test-e2e-smoke
46
46
  # with everything the slice does not own deselected — so a slice cannot miss a
47
47
  # test or run one twice, which per-slice file lists and `-k` filters both did.
48
48
  # Which tests a slice owns, and what each costs, is E2E_SLICES in
49
- # tests/e2e/conftest.py; `just e2e-slice-costs` prints the balance.
49
+ # tests/e2e/conftest.py; `just e2e-slice-costs` prints the cost model.
50
50
  test-e2e-slice slice:
51
51
  ROSOTACOM_RUN_E2E=1 {{python}} -m pytest -q --durations=0 tests/e2e/ -m e2e --e2e-slice={{slice}}
52
52
 
@@ -477,15 +477,31 @@ Given a base topic like `/tf`, stages are applied in this order:
477
477
 
478
478
  1) base topic (e.g. `/tf`)
479
479
  2) restamp → `+ shared.processing_suffixes.restamped` (default `/restamped`)
480
- 3) drop → `+ /drop{drop_count}of{window_size}` (e.g. `/drop2of3`)
481
- 4) throttle → `+ /max{hz}hz`
482
- 5) pixel cap → `+ /{preset}`
483
- 6) framebridge:
480
+ 3) latch → `+ shared.processing_suffixes.latched` (default `/latched`)
481
+ 4) drop → `+ /drop{drop_count}of{window_size}` (e.g. `/drop2of3`)
482
+ 5) throttle → `+ /max{hz}hz`
483
+ 6) pixel cap → `+ /{preset}`
484
+ 7) framebridge:
484
485
  - `local_to_global`: appended to the current topic state via `+ /globalframe`
485
486
  - `global_to_local`: appended to the base topic via `+ /globalframe` (configured inbound-side)
486
- 7) compress → `+ /<algorithm>` (default `/bz2`)
487
- 8) transport → `+ /<type>` (e.g. `/ffmpeg`, `/foxglove`, `/compressed`)
488
- 9) optional `local_republish: true` triggers reverse-transport configuration.
487
+ 8) compress → `+ /<algorithm>` (default `/bz2`)
488
+ 9) transport → `+ /<type>` (e.g. `/ffmpeg`, `/foxglove`, `/compressed`)
489
+ 10) OTA wrapper `+ /ota_stamped`
490
+
491
+ The wrapper is **always last**. Its `seq` and send stamp are read as a statement
492
+ about the traffic on the link, so it has to wrap exactly what crosses it — an
493
+ encoded stream is wrapped as `<base>/<type>/ota_stamped`, not the other way
494
+ round. Nothing may append a suffix after it, or the delivered topic would be
495
+ renamed under a receiver that subscribes by a fixed name.
496
+
497
+ The receiver undoes the chain in reverse, and every stage there is computed from
498
+ the delivered topic rather than from the OTA topic:
499
+
500
+ 1) unwrap → republishes on the pre-wrap name (so wrapping renames nothing)
501
+ 2) `local_republish: true` → reverse transport decodes into `+ /raw`
502
+ 3) decompress → republishes on the pre-compress name
503
+ 4) framebridge `global_to_local` → the local base topic
504
+ 5) trickle → `+ /trickle`, the only receiver-side stage that adds a suffix
489
505
 
490
506
  #### Transport parameters
491
507
  `type: ffmpeg` supports:
@@ -3661,14 +3661,29 @@ def _ota_wait_for_running_container_suffix_script(suffix: str, label: str, timeo
3661
3661
  )
3662
3662
 
3663
3663
 
3664
+ def _ota_communication_wait_suffix(runtime: RuntimeConfig, remote_peer_name: str) -> str:
3665
+ """What the application windows wait for, following `_container_name`.
3666
+
3667
+ The wait must make the same naming decision the start makes, or it waits
3668
+ forever for a name that will never exist: a project with
3669
+ `com_container_prefix` names its com container `<prefix>_com-to-<peer>`,
3670
+ and the instance-scoped `_com_to_<peer>` suffix matches nothing (#254).
3671
+ """
3672
+ fixed = _fixed_com_container_name(runtime, remote_peer_name)
3673
+ if fixed is not None:
3674
+ return fixed
3675
+ return _sanitize_docker_name(f"_com_to_{remote_peer_name}")
3676
+
3677
+
3664
3678
  def _ota_application_run_script(
3665
3679
  plan: OtaSmokePlan,
3666
3680
  target: InteractiveSmokeTarget,
3667
3681
  peer_name: str,
3668
3682
  application: ScenarioApplication,
3669
3683
  instance_id: str,
3684
+ runtime: RuntimeConfig,
3670
3685
  ) -> str:
3671
- communication_suffix = _sanitize_docker_name(f"_com_to_{_remote_peer_name(target.cfg, peer_name)}")
3686
+ communication_suffix = _ota_communication_wait_suffix(runtime, _remote_peer_name(target.cfg, peer_name))
3672
3687
  label = f"{peer_name}:{application.name}"
3673
3688
  command = _ota_rosotacom_command(
3674
3689
  plan, _ota_application_parts(target, peer_name, application, instance_id), plan.peers[peer_name]
@@ -3825,7 +3840,7 @@ def _ota_create_tmux(
3825
3840
  for peer in peers:
3826
3841
  for application in target.scenario_definition.applications.get(peer.name, ()):
3827
3842
  application_script = _ota_application_run_script(
3828
- plan, target, peer.name, application, instance.instance_id
3843
+ plan, target, peer.name, application, instance.instance_id, runtime
3829
3844
  )
3830
3845
  created_application = subprocess.run(
3831
3846
  _tmux_command(
@@ -1,10 +1,10 @@
1
1
  """Content-addressed names for the images this project builds.
2
2
 
3
- Every e2e job rebuilds the same project image from scratch, and #236 measured
4
- what that costs: 154s per job, thirteen jobs per merge-gate run. Publishing the
5
- built image once and adopting it in each job removes the build — but only if
6
- "adopt" can never mean "adopt something else". A cached image that no longer
7
- matches its build inputs is a silent wrong-result machine, which is why #226
3
+ Every e2e job used to rebuild the same project image from scratch, and #236
4
+ measured what that cost: 154s per job across the thirteen jobs in that run.
5
+ Publishing the built image once and adopting it in each job removes the build —
6
+ but only if "adopt" can never mean "adopt something else". A cached image that
7
+ no longer matches its build inputs is a silent wrong-result machine, which is why #226
8
8
  declined to do this inline.
9
9
 
10
10
  So the name of a published image is a hash of everything that determines it:
@@ -27,15 +27,23 @@
27
27
  // The base is ros-base, not desktop-full: 299 MB compressed against 1422 MB,
28
28
  // and nothing here runs a GUI (enable_gui_forwarding is false above). The
29
29
  // e2e suite was run against both to find out what desktop-full had been
30
- // providing without anyone declaring it one package, ros-kilted-gps-msgs,
31
- // which the anonymized remote-assist session needs for gps_msgs/msg/GPSFix.
32
- // It is declared below. Add rviz2 or a simulator here if you want them; that
33
- // is a project's decision, not a default.
30
+ // providing without anyone declaring it. It named ros-kilted-gps-msgs, for
31
+ // the gps_msgs/msg/GPSFix the anonymized remote-assist session publishes.
32
+ //
33
+ // It could not name ros-kilted-compressed-image-transport, and that one is
34
+ // why this list is not just an inventory: no e2e session has a /compressed
35
+ // input topic, so the suite never loaded compressed_sub. A vehicle camera
36
+ // does, on both ends of the link — the sender republishes compressed to
37
+ // ffmpeg, the receiver decodes back to the CompressedImage twin. Declaring
38
+ // ros-kilted-image-transport alone gets you raw and nothing else.
39
+ //
40
+ // Add rviz2 or a simulator here if you want them; that is a project's
41
+ // decision, not a default.
34
42
  "build_args": {
35
43
  "BASE_IMAGE": "ros:kilted-ros-base-noble",
36
44
  "DIGEST": "@sha256:4ca53d5b084bdbe92a7a7d7186f56db6a716a6c7c33ad401ddb0ec82d6e9e479",
37
45
  "INSTALL_ZENOH": "1",
38
- "APT_PACKAGES": "iputils-ping psmisc net-tools snmp iw nload iftop iproute2 tshark ros-kilted-domain-bridge ros-kilted-rmw-cyclonedds-cpp ros-kilted-rmw-zenoh-cpp ros-kilted-topic-tools ros-kilted-image-transport ros-kilted-ffmpeg-image-transport ros-kilted-ffmpeg-image-transport-msgs ros-kilted-gps-msgs",
46
+ "APT_PACKAGES": "iputils-ping psmisc net-tools snmp iw nload iftop iproute2 tshark ros-kilted-domain-bridge ros-kilted-rmw-cyclonedds-cpp ros-kilted-rmw-zenoh-cpp ros-kilted-topic-tools ros-kilted-image-transport ros-kilted-compressed-image-transport ros-kilted-ffmpeg-image-transport ros-kilted-ffmpeg-image-transport-msgs ros-kilted-gps-msgs",
39
47
  "PIP_PACKAGES": "numpy>=1.26,<2 lz4 pysnmp speedtest-cli psutil zstandard opencv-python"
40
48
  }
41
49
  }
@@ -52,6 +52,17 @@ topics:
52
52
  local_republish: true
53
53
  gop_size: 4
54
54
  bit_rate: 2000000
55
+ # Wrapping an encoded stream: the wrapper runs after the encoder, so the
56
+ # envelope carries the FFMPEGPacket that actually crosses the link, and
57
+ # the unwrapper republishes onto `/camera/image/ffmpeg` -- the name the
58
+ # reverse republish already decodes from. Nothing downstream is renamed,
59
+ # which is what this example proves end to end.
60
+ use_ota_wrapper: true
55
61
  expect:
56
62
  hz: { min: 3, max: 8 }
57
63
  latency_ms: { max: 1000 }
64
+ # The bound is the same 30% the video-quality check tolerates on this
65
+ # synthetic link; the assertion's purpose is that the number exists at
66
+ # all. Without the wrapper an encoded stream has no per-message
67
+ # accounting, and `loss_pct` on a topic that cannot report it fails.
68
+ loss_pct: { max: 30 }
@@ -27,15 +27,23 @@
27
27
  // The base is ros-base, not desktop-full: 299 MB compressed against 1422 MB,
28
28
  // and nothing here runs a GUI (enable_gui_forwarding is false above). The
29
29
  // e2e suite was run against both to find out what desktop-full had been
30
- // providing without anyone declaring it one package, ros-kilted-gps-msgs,
31
- // which the anonymized remote-assist session needs for gps_msgs/msg/GPSFix.
32
- // It is declared below. Add rviz2 or a simulator here if you want them; that
33
- // is a project's decision, not a default.
30
+ // providing without anyone declaring it. It named ros-kilted-gps-msgs, for
31
+ // the gps_msgs/msg/GPSFix the anonymized remote-assist session publishes.
32
+ //
33
+ // It could not name ros-kilted-compressed-image-transport, and that one is
34
+ // why this list is not just an inventory: no e2e session has a /compressed
35
+ // input topic, so the suite never loaded compressed_sub. A vehicle camera
36
+ // does, on both ends of the link — the sender republishes compressed to
37
+ // ffmpeg, the receiver decodes back to the CompressedImage twin. Declaring
38
+ // ros-kilted-image-transport alone gets you raw and nothing else.
39
+ //
40
+ // Add rviz2 or a simulator here if you want them; that is a project's
41
+ // decision, not a default.
34
42
  "build_args": {
35
43
  "BASE_IMAGE": "ros:kilted-ros-base-noble",
36
44
  "DIGEST": "@sha256:4ca53d5b084bdbe92a7a7d7186f56db6a716a6c7c33ad401ddb0ec82d6e9e479",
37
45
  "INSTALL_ZENOH": "1",
38
- "APT_PACKAGES": "iputils-ping psmisc net-tools snmp iw nload iftop iproute2 tshark ros-kilted-domain-bridge ros-kilted-rmw-cyclonedds-cpp ros-kilted-rmw-zenoh-cpp ros-kilted-topic-tools ros-kilted-image-transport ros-kilted-ffmpeg-image-transport ros-kilted-ffmpeg-image-transport-msgs ros-kilted-gps-msgs",
46
+ "APT_PACKAGES": "iputils-ping psmisc net-tools snmp iw nload iftop iproute2 tshark ros-kilted-domain-bridge ros-kilted-rmw-cyclonedds-cpp ros-kilted-rmw-zenoh-cpp ros-kilted-topic-tools ros-kilted-image-transport ros-kilted-compressed-image-transport ros-kilted-ffmpeg-image-transport ros-kilted-ffmpeg-image-transport-msgs ros-kilted-gps-msgs",
39
47
  "PIP_PACKAGES": "numpy>=1.26,<2 lz4 pysnmp speedtest-cli psutil zstandard opencv-python"
40
48
  }
41
49
  }
@@ -75,6 +75,7 @@ from com_py.status_overview_core import (
75
75
  StatusAggregator,
76
76
  collect_stage_metadata,
77
77
  collect_stage_topics,
78
+ stamp_delay,
78
79
  )
79
80
 
80
81
  ECHO_HEARTBEAT_TYPE = "com_msgs/msg/EchoHeartbeat"
@@ -274,12 +275,26 @@ class StageObserver(Node):
274
275
  stamp = getattr(header, "stamp", None) if header is not None else None
275
276
  if stamp is not None:
276
277
  try:
277
- msg_time = rclpy.time.Time.from_msg(stamp)
278
- d = (now_ros - msg_time).nanoseconds / 1e9
279
- if -1.0 < d < 1000.0: # guard unsynced clocks / zero stamps
280
- delay_s = d
278
+ stamp_s = _stamp_seconds(stamp)
281
279
  except Exception:
282
- delay_s = None
280
+ stamp_s = None
281
+ if stamp_s is not None:
282
+ d = now_ros_s - stamp_s
283
+ # An inbound stage carries a stamp written by the peer's
284
+ # clock, so it is comparable to ours only once the offset
285
+ # the heartbeat measures is applied -- exactly what the
286
+ # OtaStamped branch above does with `t_wrap`. A local
287
+ # stage was stamped by this machine and must stay raw.
288
+ contexts = self._stage_metadata.get(topic, [])
289
+ peer_stamped = any(
290
+ context.get("direction") == "inbound" for context in contexts
291
+ )
292
+ estimate = self.clock_estimator.estimate() if peer_stamped else None
293
+ if estimate is not None:
294
+ clock_offset_s = estimate["offset_s"]
295
+ rtt_s = estimate["rtt_s"]
296
+ raw_delay_s = d
297
+ delay_s = stamp_delay(d, clock_offset_s)
283
298
 
284
299
  obs.record(
285
300
  size,
@@ -148,6 +148,33 @@ class ClockOffsetEstimator:
148
148
  }
149
149
 
150
150
 
151
+ #: Plausibility window (seconds) for a latency derived from a message header
152
+ #: stamp. Outside it the number is not a latency but an unset stamp (epoch 0) or
153
+ #: a clock difference no offset estimate explains.
154
+ STAMP_DELAY_MIN_S = -1.0
155
+ STAMP_DELAY_MAX_S = 1000.0
156
+
157
+
158
+ def stamp_delay(raw_delay_s: float, clock_offset_s: Optional[float] = None) -> Optional[float]:
159
+ """Latency from a header stamp, corrected by the estimated peer clock offset.
160
+
161
+ ``raw_delay_s`` is ``local_now - stamp``. ``clock_offset_s`` is peer clock
162
+ minus local clock (as ``ClockOffsetEstimator`` reports it), so the corrected
163
+ delay is their sum -- the same arithmetic the OtaStamped path uses on its
164
+ ``t_wrap``.
165
+
166
+ Returns ``None`` when the result falls outside the plausibility window. The
167
+ guard is applied to the corrected value on purpose: a topic whose stamp is
168
+ written by the peer used to be dropped for an offset this node has already
169
+ measured, which reads as "no latency available" instead of "latency, once
170
+ the clocks are reconciled".
171
+ """
172
+ corrected = raw_delay_s if clock_offset_s is None else raw_delay_s + clock_offset_s
173
+ if STAMP_DELAY_MIN_S < corrected < STAMP_DELAY_MAX_S:
174
+ return corrected
175
+ return None
176
+
177
+
151
178
  # --- Link overhead (session-level) -----------------------------------------
152
179
 
153
180
  def _payload_kbps(stage: Optional[Dict[str, Any]]) -> float: