rosotacom-dev 2.5.dev27__tar.gz → 2.5.dev29__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 (344) hide show
  1. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/workflows/nightly-e2e.yml +23 -5
  2. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/workflows/pr-merge-gate.yml +31 -14
  3. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/workflows/release.yml +19 -2
  4. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/PKG-INFO +1 -1
  5. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/ci.md +39 -31
  6. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/testing.md +14 -9
  7. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/justfile +1 -1
  8. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/cli.py +17 -2
  9. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/image_cache.py +5 -5
  10. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom_dev.egg-info/PKG-INFO +1 -1
  11. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
  12. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_benched_set_registry.py +3 -2
  13. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_security_maintenance_config.py +10 -6
  14. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_workflow_contracts.py +15 -16
  15. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/e2e/conftest.py +25 -12
  16. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_cli.py +42 -0
  17. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.devcontainer/devcontainer.json.template +0 -0
  18. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.devcontainer/re_generate_devcontainer_json.py +0 -0
  19. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/CODEOWNERS +0 -0
  20. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
  21. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
  22. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
  23. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
  24. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
  25. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
  26. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
  27. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
  28. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  29. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/actions/setup-just/action.yml +0 -0
  30. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/dependabot.yml +0 -0
  31. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/workflows/benchmark-calibrate.yml +0 -0
  32. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/workflows/benchmark-gate.yml +0 -0
  33. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/workflows/dev-release.yml +0 -0
  34. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/workflows/image-scan.yml +0 -0
  35. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.github/workflows/pr-lightweight.yml +0 -0
  36. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/.pre-commit-config.yaml +0 -0
  37. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/AGENTS.md +0 -0
  38. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/CONCURRENCY.md +0 -0
  39. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/CONTRIBUTING.md +0 -0
  40. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/DEVELOPMENT_PRINCIPLES.md +0 -0
  41. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/LICENSE.txt +0 -0
  42. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/MANIFEST.in +0 -0
  43. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/README.md +0 -0
  44. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/budgets.jsonl +0 -0
  45. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/calibration/README.md +0 -0
  46. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/calibration/capacity-size-tight-cyclone.json +0 -0
  47. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
  48. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/calibration/probe-loss-nominal-cyclone.json +0 -0
  49. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/calibration/probe-loss-tight-cyclone.json +0 -0
  50. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/calibration/probe-loss-tight-fastdds.json +0 -0
  51. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/calibration/probe-loss-tight-zenoh.json +0 -0
  52. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/codecov.yml +0 -0
  53. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/deployment-configuration.md +0 -0
  54. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/benchmark-ab.md +0 -0
  55. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/benchmark-bag-as-load.md +0 -0
  56. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/ffmpeg-keyframes.md +0 -0
  57. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/findings/README.md +0 -0
  58. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
  59. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/findings/delay-alone-no-loss.md +0 -0
  60. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/findings/head-of-line-irregularity.md +0 -0
  61. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
  62. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/findings/lighter-message-loss.md +0 -0
  63. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
  64. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/forensics-report.md +0 -0
  65. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/geo-link-map.md +0 -0
  66. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/github-repository-settings.md +0 -0
  67. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/link-trace.md +0 -0
  68. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/owner-runbook.md +0 -0
  69. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/performance-bands.md +0 -0
  70. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/playbooks/README.md +0 -0
  71. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/quality-model.md +0 -0
  72. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/release-notes/TEMPLATE.md +0 -0
  73. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/release-notes/v2.1.md +0 -0
  74. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/release-notes/v2.2.md +0 -0
  75. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/release-notes/v2.3.md +0 -0
  76. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/release-notes/v2.4.md +0 -0
  77. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/release.md +0 -0
  78. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
  79. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/rfcs/0002-expectation-concepts.md +0 -0
  80. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/rfcs/0003-metric-backbone.md +0 -0
  81. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/rfcs/0004-network-profiles.md +0 -0
  82. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
  83. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/rfcs/0006-dynamic-qos.md +0 -0
  84. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/rfcs/0007-regression-gate.md +0 -0
  85. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/rfcs/README.md +0 -0
  86. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/docs/work-items.md +0 -0
  87. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/install.sh +0 -0
  88. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/media/control_center.png +0 -0
  89. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/media/echo_test.png +0 -0
  90. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/media/forensics-report-example.png +0 -0
  91. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/media/host.png +0 -0
  92. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/media/vehicle.png +0 -0
  93. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/pyproject.toml +0 -0
  94. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/requirements.txt +0 -0
  95. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/rosotacom.yaml +0 -0
  96. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/run_session_in_container.py +0 -0
  97. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/session-configuration.md +0 -0
  98. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/setup.cfg +0 -0
  99. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/__init__.py +0 -0
  100. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/__main__.py +0 -0
  101. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/anonymize.py +0 -0
  102. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/bag_ground_truth.py +0 -0
  103. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/benched_set.py +0 -0
  104. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/benchmark.py +0 -0
  105. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/benchmark_delta.py +0 -0
  106. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/bundle_check.py +0 -0
  107. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/cli_benchmark.py +0 -0
  108. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/deployment.py +0 -0
  109. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/ffmpeg_packet.py +0 -0
  110. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/forensics.py +0 -0
  111. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/geomap.py +0 -0
  112. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/network_profiles.py +0 -0
  113. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/network_shaper.py +0 -0
  114. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/plots.py +0 -0
  115. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/py.typed +0 -0
  116. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/benched-set.yaml +0 -0
  117. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/.gitignore +0 -0
  118. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/README.md +0 -0
  119. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/__init__.py +0 -0
  120. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
  121. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
  122. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/profiles.yaml +0 -0
  123. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/ros2docker.json +0 -0
  124. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
  125. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
  126. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
  127. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
  128. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
  129. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
  130. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
  131. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
  132. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
  133. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
  134. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
  135. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
  136. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
  137. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
  138. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
  139. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
  140. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  141. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
  142. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
  143. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
  144. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
  145. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
  146. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
  147. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
  148. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
  149. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
  150. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  151. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
  152. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
  153. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
  154. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
  155. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
  156. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
  157. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
  158. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
  159. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
  160. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
  161. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
  162. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
  163. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
  164. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
  165. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
  166. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
  167. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
  168. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
  169. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
  170. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
  171. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
  172. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
  173. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
  174. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
  175. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
  176. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
  177. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
  178. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
  179. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
  180. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
  181. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
  182. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
  183. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
  184. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
  185. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
  186. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
  187. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
  188. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
  189. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
  190. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
  191. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
  192. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
  193. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
  194. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ros2docker.json.example +0 -0
  195. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
  196. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
  197. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
  198. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
  199. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
  200. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
  201. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
  202. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
  203. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
  204. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
  205. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
  206. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
  207. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
  208. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
  209. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
  210. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
  211. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
  212. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
  213. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
  214. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
  215. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
  216. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
  217. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
  218. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
  219. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
  220. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
  221. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
  222. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
  223. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
  224. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
  225. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
  226. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
  227. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
  228. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
  229. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
  230. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
  231. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
  232. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
  233. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
  234. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
  235. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
  236. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
  237. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
  238. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
  239. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
  240. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
  241. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
  242. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
  243. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
  244. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
  245. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
  246. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
  247. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
  248. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
  249. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
  250. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
  251. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
  252. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
  253. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
  254. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
  255. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
  256. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +0 -0
  257. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
  258. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
  259. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
  260. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
  261. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
  262. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
  263. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
  264. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
  265. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
  266. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
  267. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
  268. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
  269. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
  270. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
  271. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
  272. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
  273. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +0 -0
  274. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
  275. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
  276. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
  277. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
  278. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
  279. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +0 -0
  280. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
  281. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
  282. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
  283. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/status_eval.py +0 -0
  284. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/stream_stats.py +0 -0
  285. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/trace_profiles.py +0 -0
  286. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/transit.py +0 -0
  287. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom/video_quality.py +0 -0
  288. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom_dev.egg-info/SOURCES.txt +0 -0
  289. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
  290. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
  291. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom_dev.egg-info/requires.txt +0 -0
  292. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom_dev.egg-info/scm_file_list.json +0 -0
  293. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
  294. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/stop_session_in_container.py +0 -0
  295. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/terminology.md +0 -0
  296. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_findings.py +0 -0
  297. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_markdown_links.py +0 -0
  298. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_ota_source_bundle.py +0 -0
  299. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_package_metadata.py +0 -0
  300. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_packaged_resources.py +0 -0
  301. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_profile_covers_generated_commands.py +0 -0
  302. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_pytest_policy.py +0 -0
  303. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_readme_examples.py +0 -0
  304. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/contract/test_session_configuration_doc.py +0 -0
  305. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/e2e/test_anonymize_e2e.py +0 -0
  306. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/e2e/test_benchmark_ab.py +0 -0
  307. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/e2e/test_benchmark_capacity.py +0 -0
  308. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/e2e/test_benchmark_replay.py +0 -0
  309. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/e2e/test_parallel_smoke.py +0 -0
  310. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/e2e/test_smoke.py +0 -0
  311. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/e2e/test_timeline_stepping.py +0 -0
  312. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/e2e/test_video_quality_e2e.py +0 -0
  313. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/sessions/generate_rmw_matrix.py +0 -0
  314. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
  315. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
  316. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
  317. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
  318. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
  319. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_anonymize.py +0 -0
  320. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_bag_ground_truth.py +0 -0
  321. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_benched_set.py +0 -0
  322. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_benchmark.py +0 -0
  323. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_benchmark_delta.py +0 -0
  324. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_bundle_check.py +0 -0
  325. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_cli_benchmark.py +0 -0
  326. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_concurrency.py +0 -0
  327. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_deployment.py +0 -0
  328. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_ffmpeg_packet.py +0 -0
  329. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_forensics.py +0 -0
  330. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_geomap.py +0 -0
  331. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_image_cache.py +0 -0
  332. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_link_bytes.py +0 -0
  333. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_link_trace.py +0 -0
  334. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_network_profiles.py +0 -0
  335. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_network_shaper.py +0 -0
  336. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_ota_xml.py +0 -0
  337. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_plots.py +0 -0
  338. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_stage_latency.py +0 -0
  339. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_status_eval.py +0 -0
  340. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_status_overview.py +0 -0
  341. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_stream_stats.py +0 -0
  342. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_trace_profiles.py +0 -0
  343. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/tests/unit/test_transit.py +0 -0
  344. {rosotacom_dev-2.5.dev27 → rosotacom_dev-2.5.dev29}/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.dev29
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
 
@@ -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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rosotacom-dev
3
- Version: 2.5.dev27
3
+ Version: 2.5.dev29
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "tag": "2.4",
3
- "distance": 27,
4
- "node": "g2b6ad70dddad15e9187b7876f4f32b01236cedd8",
3
+ "distance": 29,
4
+ "node": "g5cfc936161d0a8d247634ab00c5437cd6a9f7e99",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-08-13"
@@ -211,8 +211,9 @@ def test_merge_gate_lane_actually_selects_the_benchmark_e2e() -> None:
211
211
 
212
212
  The slice runner carries no `-k` at all now — it deselects by node id
213
213
  against E2E_SLICES — so the contract is that both benchmark E2E files are
214
- owned by a slice. Which slice is a balance decision (#226 split the
215
- capacity probes out of `runtime-tools`); that they run at all is not.
214
+ owned by a slice. Which diagnostic slice owns them is a partition decision
215
+ (#226 split the capacity probes out of `runtime-tools`, #253 rejects
216
+ cross-theme cost packing); that they run at all is not.
216
217
  """
217
218
  slice_recipe = re.search(
218
219
  r"^test-e2e-slice[^\n:]*:\n((?:\t.*\n?)+)",
@@ -60,18 +60,22 @@ def test_merge_gate_requires_non_docker_package_and_docker_smoke() -> None:
60
60
  assert "just test-e2e-slice" in merge_gate
61
61
  # Named individually rather than compared to E2E_SLICES, so that dropping a
62
62
  # slice from the manifest and the matrix together still fails here. Which
63
- # slices exist is a balance decision (#226, #235); that the gate runs the
64
- # Docker smoke suite at all is what this file is about.
63
+ # slices exist is a diagnostic/cost decision (#226, #235, #253); that the
64
+ # gate runs the Docker smoke suite at all is what this file is about.
65
65
  assert set(jobs["e2e"]["strategy"]["matrix"]["slice"]) >= {
66
66
  "heartbeat",
67
67
  "chatter",
68
- "occupancy-grid",
69
- "sized-payload",
68
+ "occupancy-grid-dds",
69
+ "occupancy-grid-zenoh",
70
+ "sized-payload-fastdds",
71
+ "sized-payload-zenoh",
70
72
  "remote-assist",
71
- "remote-assist-streams",
73
+ "remote-assist-costmap",
74
+ "remote-assist-camera",
72
75
  "runtime-tools",
73
76
  "media",
74
- "concurrency",
77
+ "concurrency-parallel",
78
+ "concurrency-conflict",
75
79
  "benchmark-ab",
76
80
  "benchmark-replay",
77
81
  "benchmark-capacity",
@@ -302,33 +302,32 @@ def test_workflow_matrices_expand_the_slices_that_exist() -> None:
302
302
 
303
303
 
304
304
  def test_e2e_slices_stay_close_to_the_floor() -> None:
305
- """Balance is a number now, so it can be kept rather than rediscovered.
305
+ """Diagnostic slices reach the floor without cross-theme packing.
306
306
 
307
307
  Themed slices drifted to a 2.4x spread (7m39s against 18m31s) with nobody
308
308
  noticing, because the only place a per-test cost existed was a `pytest -q`
309
309
  total that nothing compared.
310
310
 
311
- Measured against the floor rather than the spread, which is what this test
312
- asserted at six slices and what stopped meaning anything at thirteen. The
313
- fixed cost per job compresses spread toward 1.0 as N grows, so a suite could
314
- go badly wrong while spread still read 1.1; and past N=12 the spread is set
315
- by tests too small to split rather than by imbalance. Distance to
316
- `floor_seconds()` says the one thing worth asserting at any N — the gate is
317
- near the fastest it could possibly be and needs no retuning when a test is
318
- added.
319
-
320
- 1.25x, not 1.0x, because the floor assumes tests can be divided arbitrarily
321
- and they cannot. At thirteen slices the partition sits at 1.09x.
311
+ The cost model remains useful, but #253 makes the slice name the stronger
312
+ constraint: costs can require another runner inside a theme, never move a
313
+ test behind an unrelated name. The four groups above the floor all had a
314
+ diagnostic seam (transport, stream, or concurrency behavior), so seventeen
315
+ named slices reach 1.00x without arbitrary packing.
316
+
317
+ Exact distance to the floor keeps that choice durable. A new grouped slice
318
+ above it must be split on a useful diagnostic boundary; spare seconds in an
319
+ unrelated slice are not capacity to fill.
322
320
  """
323
321
  module = _e2e_conftest()
324
322
  predicted = {name: module.predicted_slice_seconds(name) for name in module.E2E_SLICES}
325
323
  slowest = max(predicted.values())
326
324
  floor = module.floor_seconds()
327
325
 
328
- assert slowest <= 1.25 * floor, (
326
+ assert slowest <= floor, (
329
327
  f"the slowest e2e slice is predicted at {slowest / 60:.2f}m against a "
330
- f"{floor / 60:.2f}m floor ({slowest / floor:.2f}x). Move tests between slices, "
331
- f"or split the slowest one, in tests/e2e/conftest.py:\n{module.slice_cost_report()}"
328
+ f"{floor / 60:.2f}m floor ({slowest / floor:.2f}x). Split the slowest "
329
+ "slice on a diagnostic boundary; do not move tests into an unrelated "
330
+ f"slice:\n{module.slice_cost_report()}"
332
331
  )
333
332
 
334
333
 
@@ -446,7 +445,7 @@ def test_e2e_waits_only_for_the_cheap_gate_and_the_image() -> None:
446
445
  `needs: preflight-success` made every gate run wait 2.15 min for the
447
446
  five-version `merge-lightweight` matrix. It had stopped an e2e round once
448
447
  in sixty runs — on `workflow-lint`, which takes 0.12 min. `ci-success`
449
- still requires every preflight job, so this is a change to when thirteen
448
+ still requires every preflight job, so this is a change to when seventeen
450
449
  runners start, not to what may merge.
451
450
  """
452
451
  workflow = yaml.safe_load((WORKFLOWS_DIR / "pr-merge-gate.yml").read_text(encoding="utf-8"))
@@ -1,7 +1,7 @@
1
1
  """Collection rules for the Docker-backed e2e suite, and the CI slice partition.
2
2
 
3
3
  `just test-e2e-smoke` runs the whole suite in one process; CI runs the same
4
- collection as thirteen parallel slices, selected with `--e2e-slice=<name>`. A
4
+ collection as seventeen parallel slices, selected with `--e2e-slice=<name>`. A
5
5
  slice is a deselection of one shared collection, not a separate pytest
6
6
  invocation with its own file list — which is what it used to be, and that shape
7
7
  got two things wrong that a partition cannot get wrong:
@@ -16,8 +16,10 @@ got two things wrong that a partition cannot get wrong:
16
16
 
17
17
  The number next to each test is what it costs. #226 balanced six themed slices
18
18
  on those numbers and the run came back within 25s of every prediction, so #235
19
- used the same model to choose N instead of guessing it: thirteen slices, split
20
- where the tests already differ, is 1.09x the fastest any partition could be.
19
+ used the same model to choose N instead of guessing it. #253 makes diagnosis
20
+ the stronger constraint: costs decide when a theme needs another runner, but
21
+ unrelated tests are never packed together merely because their durations fit.
22
+ Seventeen is the smallest theme-preserving partition that reaches the floor.
21
23
  """
22
24
 
23
25
  from __future__ import annotations
@@ -97,26 +99,33 @@ E2E_SLICES: dict[str, dict[str, float]] = {
97
99
  "tests/e2e/test_smoke.py::test_interactive_native_chatter_smoke_starts_full_local_debug_rig": 74.4,
98
100
  },
99
101
  # `transforms` was one slice over two unrelated questions. Compression and
100
- # payload size each keep their RMW pair together, because the pair is the
101
- # comparison: a red job here means "this transform, both transports" or
102
- # "this transform, one transport", which is the first thing you ask.
103
- "occupancy-grid": {
102
+ # payload size were then kept as transport pairs, but both pairs grew past
103
+ # the floor. A job per transport now names both the transform and the
104
+ # transport that failed instead of hiding that distinction in pytest output.
105
+ "occupancy-grid-dds": {
104
106
  "tests/e2e/test_smoke.py::test_local_compressed_occupancy_grid_smoke_from_copied_example_project[compressed-occupancy-grid]": 158.3, # derived
107
+ },
108
+ "occupancy-grid-zenoh": {
105
109
  "tests/e2e/test_smoke.py::test_local_zenoh_compressed_occupancy_grid_smoke_from_copied_example_project[compressed-occupancy-grid-zenoh]": 150.4,
106
110
  },
107
- "sized-payload": {
108
- "tests/e2e/test_smoke.py::test_local_zenoh_sized_payload_smoke_from_copied_example_project[sized-payload-zenoh]": 172.5,
111
+ "sized-payload-fastdds": {
109
112
  "tests/e2e/test_smoke.py::test_local_wrapped_sized_payload_smoke_from_copied_example_project[sized-payload-fastdds]": 117.4,
110
113
  },
114
+ "sized-payload-zenoh": {
115
+ "tests/e2e/test_smoke.py::test_local_zenoh_sized_payload_smoke_from_copied_example_project[sized-payload-zenoh]": 172.5,
116
+ },
111
117
  # The full anonymized rig, alone: at 267s warm it is the slowest single test
112
118
  # in the suite and therefore sets the floor every other slice is measured
113
119
  # against. Nothing can share a job with it and stay under that floor.
114
120
  "remote-assist": {
115
121
  "tests/e2e/test_smoke.py::test_local_remote_assist_anonymized_smoke_from_copied_example_project[remote-assist-anonymized]": 267.0,
116
122
  },
117
- # Its two single-stream cuts, which share a trace with the rig above.
118
- "remote-assist-streams": {
123
+ # Its two single-stream cuts share a trace with the rig above, but exercise
124
+ # different processing paths and should name which stream failed.
125
+ "remote-assist-costmap": {
119
126
  "tests/e2e/test_smoke.py::test_local_single_stream_anonymized_smoke_from_copied_example_project[remote-assist-anonymized-costmap]": 145.2,
127
+ },
128
+ "remote-assist-camera": {
120
129
  "tests/e2e/test_smoke.py::test_local_single_stream_anonymized_smoke_from_copied_example_project[remote-assist-anonymized-camera]": 145.1,
121
130
  },
122
131
  # What a live session exposes and what can be changed under it.
@@ -128,8 +137,12 @@ E2E_SLICES: dict[str, dict[str, float]] = {
128
137
  "tests/e2e/test_video_quality_e2e.py::test_synthetic_camera_pipeline_records_quality_metrics": 161.8,
129
138
  "tests/e2e/test_anonymize_e2e.py::test_anonymize_headless_end_to_end_preserves_keyframe_structure": 10.4, # derived
130
139
  },
131
- "concurrency": {
140
+ # These are complementary concurrency guarantees, but a failure in safe
141
+ # parallel execution says something different from a rejected conflict.
142
+ "concurrency-parallel": {
132
143
  "tests/e2e/test_parallel_smoke.py::test_independent_local_smoke_tests_run_in_parallel": 146.6,
144
+ },
145
+ "concurrency-conflict": {
133
146
  "tests/e2e/test_parallel_smoke.py::test_second_same_target_smoke_aborts_and_leaves_first_intact": 125.0,
134
147
  },
135
148
  # The two benchmark verdicts, one job each: at 202s and 174s neither fits