rosotacom-dev 2.2__tar.gz → 2.4__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 (340) hide show
  1. rosotacom_dev-2.4/.github/workflows/dev-release.yml +152 -0
  2. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/workflows/release.yml +23 -0
  3. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/AGENTS.md +15 -0
  4. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/CONTRIBUTING.md +19 -6
  5. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/PKG-INFO +54 -5
  6. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/README.md +53 -4
  7. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/ci.md +6 -2
  8. rosotacom_dev-2.4/docs/release-notes/v2.3.md +34 -0
  9. rosotacom_dev-2.4/docs/release-notes/v2.4.md +46 -0
  10. rosotacom_dev-2.4/docs/release.md +104 -0
  11. rosotacom_dev-2.4/src/rosotacom/__init__.py +42 -0
  12. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/cli.py +377 -66
  13. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom_dev.egg-info/PKG-INFO +54 -5
  14. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom_dev.egg-info/SOURCES.txt +4 -0
  15. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom_dev.egg-info/scm_file_list.json +273 -269
  16. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom_dev.egg-info/scm_version.json +2 -2
  17. rosotacom_dev-2.4/tests/contract/test_ota_source_bundle.py +120 -0
  18. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/contract/test_packaged_resources.py +46 -0
  19. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_cli.py +140 -0
  20. rosotacom_dev-2.2/docs/release.md +0 -51
  21. rosotacom_dev-2.2/src/rosotacom/__init__.py +0 -32
  22. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.devcontainer/devcontainer.json.template +0 -0
  23. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.devcontainer/re_generate_devcontainer_json.py +0 -0
  24. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/CODEOWNERS +0 -0
  25. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/ISSUE_TEMPLATE/documentation-audit.md +0 -0
  26. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/ISSUE_TEMPLATE/implementation-cleanup.md +0 -0
  27. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/ISSUE_TEMPLATE/quality-workflow.md +0 -0
  28. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/ISSUE_TEMPLATE/redesign.md +0 -0
  29. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/ISSUE_TEMPLATE/release-process.md +0 -0
  30. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/ISSUE_TEMPLATE/repository-diagnosis.md +0 -0
  31. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/ISSUE_TEMPLATE/test-ci-audit.md +0 -0
  32. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/ISSUE_TEMPLATE/work-item.md +0 -0
  33. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  34. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/dependabot.yml +0 -0
  35. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/workflows/benchmark-calibrate.yml +0 -0
  36. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/workflows/benchmark-gate.yml +0 -0
  37. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/workflows/image-scan.yml +0 -0
  38. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/workflows/nightly-e2e.yml +0 -0
  39. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/workflows/pr-lightweight.yml +0 -0
  40. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.github/workflows/pr-merge-gate.yml +0 -0
  41. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/.pre-commit-config.yaml +0 -0
  42. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/CONCURRENCY.md +0 -0
  43. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/DEVELOPMENT_PRINCIPLES.md +0 -0
  44. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/LICENSE.txt +0 -0
  45. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/MANIFEST.in +0 -0
  46. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/budgets.jsonl +0 -0
  47. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/calibration/README.md +0 -0
  48. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/calibration/capacity-size-tight-cyclone.json +0 -0
  49. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/calibration/probe-loss-gop-tight-cyclone.json +0 -0
  50. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/calibration/probe-loss-nominal-cyclone.json +0 -0
  51. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/calibration/probe-loss-tight-cyclone.json +0 -0
  52. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/calibration/probe-loss-tight-fastdds.json +0 -0
  53. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/calibration/probe-loss-tight-zenoh.json +0 -0
  54. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/codecov.yml +0 -0
  55. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/deployment-configuration.md +0 -0
  56. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/benchmark-ab.md +0 -0
  57. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/benchmark-bag-as-load.md +0 -0
  58. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/ffmpeg-keyframes.md +0 -0
  59. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/findings/README.md +0 -0
  60. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/findings/cyclone-spdp-discovery-bursts.md +0 -0
  61. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/findings/delay-alone-no-loss.md +0 -0
  62. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/findings/head-of-line-irregularity.md +0 -0
  63. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/findings/jitter-loss-bandwidth-latency.md +0 -0
  64. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/findings/lighter-message-loss.md +0 -0
  65. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/findings/zero-loss-boundaries-18kb-20hz.md +0 -0
  66. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/forensics-report.md +0 -0
  67. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/geo-link-map.md +0 -0
  68. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/github-repository-settings.md +0 -0
  69. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/link-trace.md +0 -0
  70. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/owner-runbook.md +0 -0
  71. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/performance-bands.md +0 -0
  72. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/playbooks/README.md +0 -0
  73. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/quality-model.md +0 -0
  74. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/release-notes/TEMPLATE.md +0 -0
  75. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/release-notes/v2.1.md +0 -0
  76. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/release-notes/v2.2.md +0 -0
  77. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/rfcs/0001-expectation-driven-test-suite.md +0 -0
  78. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/rfcs/0002-expectation-concepts.md +0 -0
  79. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/rfcs/0003-metric-backbone.md +0 -0
  80. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/rfcs/0004-network-profiles.md +0 -0
  81. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/rfcs/0005-benchmark-genres-and-ci.md +0 -0
  82. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/rfcs/0006-dynamic-qos.md +0 -0
  83. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/rfcs/0007-regression-gate.md +0 -0
  84. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/rfcs/README.md +0 -0
  85. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/testing.md +0 -0
  86. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/docs/work-items.md +0 -0
  87. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/install.sh +0 -0
  88. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/justfile +0 -0
  89. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/media/control_center.png +0 -0
  90. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/media/echo_test.png +0 -0
  91. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/media/forensics-report-example.png +0 -0
  92. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/media/host.png +0 -0
  93. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/media/vehicle.png +0 -0
  94. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/pyproject.toml +0 -0
  95. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/requirements.txt +0 -0
  96. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/rosotacom.yaml +0 -0
  97. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/run_session_in_container.py +0 -0
  98. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/session-configuration.md +0 -0
  99. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/setup.cfg +0 -0
  100. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/__main__.py +0 -0
  101. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/anonymize.py +0 -0
  102. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/bag_ground_truth.py +0 -0
  103. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/benched_set.py +0 -0
  104. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/benchmark.py +0 -0
  105. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/bundle_check.py +0 -0
  106. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/cli_benchmark.py +0 -0
  107. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/deployment.py +0 -0
  108. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/ffmpeg_packet.py +0 -0
  109. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/forensics.py +0 -0
  110. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/geomap.py +0 -0
  111. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/network_profiles.py +0 -0
  112. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/network_shaper.py +0 -0
  113. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/plots.py +0 -0
  114. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/py.typed +0 -0
  115. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/benched-set.yaml +0 -0
  116. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/.gitignore +0 -0
  117. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/README.md +0 -0
  118. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/__init__.py +0 -0
  119. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/bags/8_drop_reference/metadata.yaml +0 -0
  120. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/deployment.example.yaml +0 -0
  121. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/profiles.yaml +0 -0
  122. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/ros2docker.json +0 -0
  123. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/rosotacom.yaml +0 -0
  124. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scenarios/2_native_chatter/scenario-definition.yaml +0 -0
  125. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_a.sh +0 -0
  126. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/1_heartbeat/run_machine_b.sh +0 -0
  127. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/external.ros2docker.json +0 -0
  128. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_communication.sh +0 -0
  129. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/run_external.py +0 -0
  130. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_a/wait_for_echo_topic.sh +0 -0
  131. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/external.ros2docker.json +0 -0
  132. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_communication.sh +0 -0
  133. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/2_native_chatter/machine_b/run_external.py +0 -0
  134. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external.ros2docker.json +0 -0
  135. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/external_session.yaml +0 -0
  136. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/foxglove.json +0 -0
  137. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_communication.sh +0 -0
  138. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_a/run_external.py +0 -0
  139. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  140. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/costmap_1second/metadata.yaml +0 -0
  141. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/external.ros2docker.json +0 -0
  142. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_communication.sh +0 -0
  143. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/3_comp_occ_grid/machine_b/run_external.py +0 -0
  144. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external.ros2docker.json +0 -0
  145. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/external_session.yaml +0 -0
  146. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/foxglove.json +0 -0
  147. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_communication.sh +0 -0
  148. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_a/run_external.py +0 -0
  149. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/costmap_1second_0.mcap +0 -0
  150. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/costmap_1second/metadata.yaml +0 -0
  151. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/external.ros2docker.json +0 -0
  152. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_communication.sh +0 -0
  153. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/4_comp_occ_grid_zen/machine_b/run_external.py +0 -0
  154. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external.ros2docker.json +0 -0
  155. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/external_session.yaml +0 -0
  156. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_communication.sh +0 -0
  157. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_a/run_external.py +0 -0
  158. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external.ros2docker.json +0 -0
  159. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/external_session.yaml +0 -0
  160. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_communication.sh +0 -0
  161. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/5_sized_payload/machine_b/run_external.py +0 -0
  162. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external.ros2docker.json +0 -0
  163. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/external_session.yaml +0 -0
  164. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_communication.sh +0 -0
  165. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_a/run_external.py +0 -0
  166. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external.ros2docker.json +0 -0
  167. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/external_session.yaml +0 -0
  168. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_communication.sh +0 -0
  169. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/scripts/6_sized_payload_zen/machine_b/run_external.py +0 -0
  170. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/10_restamp/session-definition.yaml +0 -0
  171. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/11_trickle/session-definition.yaml +0 -0
  172. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/12_content_integrity/session-definition.yaml +0 -0
  173. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/13_link_latency/session-definition.yaml +0 -0
  174. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/14_remote_assist_anonymized/session-definition.yaml +0 -0
  175. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/15_remote_assist_anonymized_costmap/session-definition.yaml +0 -0
  176. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/16_remote_assist_anonymized_camera/session-definition.yaml +0 -0
  177. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/17_synthetic_camera_quality/session-definition.yaml +0 -0
  178. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/1_heartbeat/session-definition.yaml +0 -0
  179. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/1_heartbeat_status/session-definition.yaml +0 -0
  180. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/2_native_chatter/session-definition.yaml +0 -0
  181. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/3_comp_occ_grid/session-definition.yaml +0 -0
  182. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/4_comp_occ_grid_zen/session-definition.yaml +0 -0
  183. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/5_sized_payload/session-definition.yaml +0 -0
  184. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/6_sized_payload_zen/session-definition.yaml +0 -0
  185. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/7_latched_static/session-definition.yaml +0 -0
  186. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/8_drop/session-definition.yaml +0 -0
  187. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/9_throttle/session-definition.yaml +0 -0
  188. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/bench_1_1_capacity/session-definition.yaml +0 -0
  189. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/bench_1_2_load_sweep/session-definition.yaml +0 -0
  190. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/bench_1_3_ramp/session-definition.yaml +0 -0
  191. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/bench_1_4_recovery/session-definition.yaml +0 -0
  192. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/examples/sessions/bench_1_5_camera/session-definition.yaml +0 -0
  193. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ros2docker.json.example +0 -0
  194. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/.vscode/c_cpp_properties.json +0 -0
  195. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/.vscode/settings.json +0 -0
  196. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_easy_mode.xml.template +0 -0
  197. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_initial_peer_list.xml.template +0 -0
  198. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v2.xml.template +0 -0
  199. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v3.xml.template +0 -0
  200. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v4.xml.template +0 -0
  201. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/archive/fastdds_v5.xml.template +0 -0
  202. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/create_zenoh_json5.py +0 -0
  203. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/cyclonedds_minimal.xml.template +0 -0
  204. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/cyclonedds_tuned.xml.template +0 -0
  205. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/fastdds_unicast.xml.template +0 -0
  206. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/get_ota_xml.py +0 -0
  207. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/utils.py +0 -0
  208. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ota_configs/zenoh.json5.template +0 -0
  209. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/.gitkeep +0 -0
  210. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_cpp/CMakeLists.txt +0 -0
  211. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_cpp/COLCON_IGNORE +0 -0
  212. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_cpp/LICENSE.txt +0 -0
  213. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_cpp/package.xml +0 -0
  214. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_cpp/src/hz_monitor.cpp +0 -0
  215. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_compressor.cpp +0 -0
  216. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_cpp/src/universal_decompressor.cpp +0 -0
  217. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_msgs/CMakeLists.txt +0 -0
  218. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_msgs/LICENSE.txt +0 -0
  219. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/CompressedData.msg +0 -0
  220. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/EchoHeartbeat.msg +0 -0
  221. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/OtaStamped.msg +0 -0
  222. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_msgs/msg/SizedPayload.msg +0 -0
  223. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_msgs/package.xml +0 -0
  224. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/LICENSE.txt +0 -0
  225. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/__init__.py +0 -0
  226. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/base_bridge_relay.py +0 -0
  227. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_in.py +0 -0
  228. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/bridge_out.py +0 -0
  229. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/heartbeat_echo.py +0 -0
  230. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/hz_monitor.py +0 -0
  231. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_bandwidth_reducer.py +0 -0
  232. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/image_pixel_capper.py +0 -0
  233. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/lanelet_saver.py +0 -0
  234. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/latch_relay.py +0 -0
  235. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/costmap_remapper.py +0 -0
  236. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/marker_remapper.py +0 -0
  237. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/speed_test.py +0 -0
  238. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/tf_remapper.py +0 -0
  239. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/traffic_monitor.py +0 -0
  240. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/legacy/wifi_network_analysis_1.py +0 -0
  241. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_bytes.py +0 -0
  242. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/link_trace.py +0 -0
  243. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/local_global_frame_bridge.py +0 -0
  244. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/localization_map_split_reduce_saver.py +0 -0
  245. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/msg_transform.py +0 -0
  246. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pair_management.py +0 -0
  247. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/pub_sub_pair.py +0 -0
  248. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/qos.py +0 -0
  249. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_in.py +0 -0
  250. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/relay_out.py +0 -0
  251. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/restamp.py +0 -0
  252. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/sized_publisher.py +0 -0
  253. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency.py +0 -0
  254. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/stage_latency_core.py +0 -0
  255. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview.py +0 -0
  256. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/status_overview_core.py +0 -0
  257. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/tf_map_to_cart_saver.py +0 -0
  258. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_monitor.py +0 -0
  259. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/topic_resolution.py +0 -0
  260. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/trickle.py +0 -0
  261. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_compressor.py +0 -0
  262. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_decompressor.py +0 -0
  263. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_unwrapper.py +0 -0
  264. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/com_py/universal_ota_wrapper.py +0 -0
  265. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/package.xml +0 -0
  266. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/resource/com_py +0 -0
  267. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/setup.cfg +0 -0
  268. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/setup.py +0 -0
  269. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/test/test_copyright.py +0 -0
  270. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/test/test_flake8.py +0 -0
  271. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/ros2src/com_py/test/test_pep257.py +0 -0
  272. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/session/content/base/session_plugin_base.yaml +0 -0
  273. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/session/content/network/up_connectivity.py +0 -0
  274. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/session/content/network/wifi_network_analysis_2.py +0 -0
  275. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/session/creation/anonymize_bag.py +0 -0
  276. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/session/creation/catmux_log_setup.sh +0 -0
  277. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/session/creation/create_session_yaml.py +0 -0
  278. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/session/creation/generate_session_files.py +0 -0
  279. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/session/creation/run_session.py +0 -0
  280. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/session/creation/run_session_in_external_terminal.py +0 -0
  281. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/resources/ws/session/creation/strip_ansi.py +0 -0
  282. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/status_eval.py +0 -0
  283. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/stream_stats.py +0 -0
  284. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/trace_profiles.py +0 -0
  285. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/transit.py +0 -0
  286. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom/video_quality.py +0 -0
  287. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom_dev.egg-info/dependency_links.txt +0 -0
  288. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom_dev.egg-info/entry_points.txt +0 -0
  289. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom_dev.egg-info/requires.txt +0 -0
  290. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/src/rosotacom_dev.egg-info/top_level.txt +0 -0
  291. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/stop_session_in_container.py +0 -0
  292. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/terminology.md +0 -0
  293. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/contract/test_benched_set_registry.py +0 -0
  294. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/contract/test_findings.py +0 -0
  295. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/contract/test_markdown_links.py +0 -0
  296. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/contract/test_package_metadata.py +0 -0
  297. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/contract/test_profile_covers_generated_commands.py +0 -0
  298. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/contract/test_pytest_policy.py +0 -0
  299. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/contract/test_readme_examples.py +0 -0
  300. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/contract/test_security_maintenance_config.py +0 -0
  301. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/contract/test_workflow_contracts.py +0 -0
  302. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/e2e/conftest.py +0 -0
  303. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/e2e/test_anonymize_e2e.py +0 -0
  304. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/e2e/test_benchmark_ab.py +0 -0
  305. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/e2e/test_benchmark_capacity.py +0 -0
  306. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/e2e/test_benchmark_replay.py +0 -0
  307. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/e2e/test_parallel_smoke.py +0 -0
  308. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/e2e/test_smoke.py +0 -0
  309. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/e2e/test_timeline_stepping.py +0 -0
  310. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/e2e/test_video_quality_e2e.py +0 -0
  311. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/sessions/generate_rmw_matrix.py +0 -0
  312. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-local_zenoh-ros2dds-ota/session-definition.yaml +0 -0
  313. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota/session-definition.yaml +0 -0
  314. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/sessions/rmw_matrix/1_heartbeat_cyclone-ota-tuned/session-definition.yaml +0 -0
  315. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/sessions/rmw_matrix/1_heartbeat_fastdds/session-definition.yaml +0 -0
  316. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/sessions/rmw_matrix/1_heartbeat_zen-endpoints/session-definition.yaml +0 -0
  317. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_anonymize.py +0 -0
  318. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_bag_ground_truth.py +0 -0
  319. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_benched_set.py +0 -0
  320. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_benchmark.py +0 -0
  321. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_bundle_check.py +0 -0
  322. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_cli_benchmark.py +0 -0
  323. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_concurrency.py +0 -0
  324. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_deployment.py +0 -0
  325. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_ffmpeg_packet.py +0 -0
  326. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_forensics.py +0 -0
  327. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_geomap.py +0 -0
  328. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_link_bytes.py +0 -0
  329. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_link_trace.py +0 -0
  330. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_network_profiles.py +0 -0
  331. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_network_shaper.py +0 -0
  332. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_ota_xml.py +0 -0
  333. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_plots.py +0 -0
  334. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_stage_latency.py +0 -0
  335. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_status_eval.py +0 -0
  336. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_status_overview.py +0 -0
  337. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_stream_stats.py +0 -0
  338. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_trace_profiles.py +0 -0
  339. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_transit.py +0 -0
  340. {rosotacom_dev-2.2 → rosotacom_dev-2.4}/tests/unit/test_video_quality.py +0 -0
@@ -0,0 +1,152 @@
1
+ name: Dev release
2
+
3
+ # Every commit that lands on develop becomes an installable pre-release.
4
+ #
5
+ # Consuming this package should not mean consuming something days old. Without
6
+ # this, a downstream repository could only pin a version after someone decided
7
+ # to cut a release, so "always consume the package, never the checkout" cost a
8
+ # human decision per iteration — and the cheap way out was to stop consuming the
9
+ # package.
10
+ #
11
+ # setuptools-scm already derives X.Y.devN from the history; those wheels were
12
+ # built by CI and thrown away. This publishes them.
13
+ #
14
+ # `pip` does not resolve pre-releases unless asked, so the stable line is
15
+ # unaffected: nobody gets a dev version by accident, and anybody who wants one
16
+ # pins it exactly. Cutting a stable vX.Y stays a deliberate, human decision in
17
+ # release.yml.
18
+ #
19
+ # It runs on workflow_run rather than on push, so a commit whose CI failed is
20
+ # never published. workflow_run resolves this file from the default branch,
21
+ # which is develop — the branch it watches.
22
+
23
+ on:
24
+ workflow_run:
25
+ workflows: ["CI"]
26
+ types: [completed]
27
+ branches: [develop]
28
+
29
+ permissions:
30
+ contents: read
31
+
32
+ concurrency:
33
+ group: ${{ github.workflow }}-${{ github.event.workflow_run.head_sha }}
34
+ cancel-in-progress: false
35
+
36
+ jobs:
37
+ publish:
38
+ name: publish
39
+ runs-on: ubuntu-latest
40
+ # `event == 'push'` keeps pull-request CI runs out: only what actually
41
+ # landed on develop is published.
42
+ if: >-
43
+ github.event.workflow_run.conclusion == 'success'
44
+ && github.event.workflow_run.event == 'push'
45
+ # Same authorization as release.yml: the per-repo Trusted Publisher,
46
+ # registered with a blank environment. No token, no environment admin.
47
+ permissions:
48
+ id-token: write
49
+
50
+ steps:
51
+ - name: Check out the commit CI validated
52
+ uses: actions/checkout@v6
53
+ with:
54
+ # Pin to the validated commit: develop may have moved on since, and
55
+ # publishing a different tree than the one that passed would make the
56
+ # version meaningless.
57
+ ref: ${{ github.event.workflow_run.head_sha }}
58
+ # setuptools-scm needs the full history and the tags to derive the
59
+ # version; a shallow clone silently yields 0.1.dev1.
60
+ fetch-depth: 0
61
+
62
+ - name: Set up Python
63
+ uses: actions/setup-python@v6
64
+ with:
65
+ python-version: "3.12"
66
+ cache: pip
67
+
68
+ - name: Install just
69
+ run: |
70
+ sudo apt-get update
71
+ sudo apt-get install -y just
72
+
73
+ - name: Set up local environment
74
+ run: just setup
75
+
76
+ - name: Build and validate distributions
77
+ run: just package
78
+
79
+ - name: Require a pre-release version
80
+ id: version
81
+ run: |
82
+ set -euo pipefail
83
+ # A wheel filename is name-version-pytag-abitag-plattag.whl.
84
+ shopt -s nullglob
85
+ wheels=(dist/*.whl)
86
+ if [ "${#wheels[@]}" -ne 1 ]; then
87
+ echo "::error::expected exactly one wheel in dist/, found ${#wheels[@]}"
88
+ exit 1
89
+ fi
90
+ base="$(basename "${wheels[0]}" .whl)"
91
+ name="${base%%-*}"
92
+ rest="${base#*-}"
93
+ version="${rest%%-*}"
94
+ echo "distribution=${name//_/-}" >> "$GITHUB_OUTPUT"
95
+ echo "version=$version" >> "$GITHUB_OUTPUT"
96
+ echo "Built ${name//_/-} $version"
97
+ # A clean X.Y here means develop points at a tagged commit. That
98
+ # version belongs to the stable line and release.yml owns it, so skip
99
+ # rather than race it onto the index under a second identity.
100
+ if [ "${version#*.dev}" = "$version" ]; then
101
+ echo "::notice::$version is not a pre-release; the stable tag path owns it. Skipping."
102
+ echo "publish=false" >> "$GITHUB_OUTPUT"
103
+ else
104
+ echo "publish=true" >> "$GITHUB_OUTPUT"
105
+ fi
106
+
107
+ - name: Remove checksum sidecar
108
+ if: steps.version.outputs.publish == 'true'
109
+ run: rm -f dist/SHA256SUMS
110
+
111
+ - name: Verify configured publishing target
112
+ if: steps.version.outputs.publish == 'true'
113
+ env:
114
+ PYPI_PUBLISH_URL: ${{ vars.PYPI_PUBLISH_URL }}
115
+ run: |
116
+ if [ -z "$PYPI_PUBLISH_URL" ]; then
117
+ echo "::error::PYPI_PUBLISH_URL is not configured for this repository."
118
+ exit 1
119
+ fi
120
+ case "$PYPI_PUBLISH_URL" in
121
+ https://*) ;;
122
+ *)
123
+ echo "::error::PYPI_PUBLISH_URL must be an HTTPS endpoint (offending value: '$PYPI_PUBLISH_URL')."
124
+ exit 1
125
+ ;;
126
+ esac
127
+
128
+ # No TestPyPI rehearsal here. The dev channel *is* the rehearsal, and a
129
+ # second upload per commit would double the noise for no extra signal.
130
+ - name: Publish pre-release
131
+ if: steps.version.outputs.publish == 'true'
132
+ uses: pypa/gh-action-pypi-publish@release/v1
133
+ with:
134
+ repository-url: ${{ vars.PYPI_PUBLISH_URL }}
135
+ skip-existing: true
136
+
137
+ - name: Summarise
138
+ if: steps.version.outputs.publish == 'true'
139
+ env:
140
+ DISTRIBUTION: ${{ steps.version.outputs.distribution }}
141
+ VERSION: ${{ steps.version.outputs.version }}
142
+ COMMIT: ${{ github.event.workflow_run.head_sha }}
143
+ run: |
144
+ # Markdown code block by indentation: no backticks, which shellcheck
145
+ # would read as command substitution.
146
+ {
147
+ echo "Published $VERSION from $COMMIT."
148
+ echo
149
+ echo "Consume it with:"
150
+ echo
151
+ echo " pipx install \"$DISTRIBUTION==$VERSION\""
152
+ } >> "$GITHUB_STEP_SUMMARY"
@@ -77,6 +77,29 @@ jobs:
77
77
  - name: Build and validate distributions
78
78
  run: just package
79
79
 
80
+ # The mirror of the dev channel's guard. A tag build must produce the
81
+ # clean version the tag names; a pre-release here means the tag is not on
82
+ # the commit being built (a dirty tree, or a tag pushed from the wrong
83
+ # place), and the release would silently publish something else.
84
+ - name: Require a stable version
85
+ if: startsWith(github.ref, 'refs/tags/v')
86
+ run: |
87
+ set -euo pipefail
88
+ shopt -s nullglob
89
+ wheels=(dist/*.whl)
90
+ if [ "${#wheels[@]}" -ne 1 ]; then
91
+ echo "::error::expected exactly one wheel in dist/, found ${#wheels[@]}"
92
+ exit 1
93
+ fi
94
+ base="$(basename "${wheels[0]}" .whl)"
95
+ rest="${base#*-}"
96
+ version="${rest%%-*}"
97
+ expected="${GITHUB_REF_NAME#v}"
98
+ if [ "$version" != "$expected" ]; then
99
+ echo "::error::tag $GITHUB_REF_NAME builds version $version, not $expected."
100
+ exit 1
101
+ fi
102
+
80
103
  - name: Generate checksums
81
104
  run: |
82
105
  cd dist
@@ -43,6 +43,21 @@ Shared workflow:
43
43
  is unavailable, record why in the PR and final status.
44
44
  - Keep the PR description current with the issue link, validation commands,
45
45
  important SHAs, CI status, and any dependency on another PR or harness MR.
46
+
47
+ Release autonomy — where the human decision actually is:
48
+
49
+ - Agents run a change to the end: branch, PR, CI, auto-merge. Merging publishes
50
+ a `X.Y.devN` pre-release automatically (`.github/workflows/dev-release.yml`),
51
+ so a downstream repository can pin the result immediately. Nothing about that
52
+ needs a human, and a merged change that nobody can consume is not finished.
53
+ - Cutting a stable `vX.Y.Z` tag is the one release step that is a decision, not
54
+ a consequence: the version is a promise to consumers and cannot be taken back
55
+ once it is on the index. Cut one only when the task says so.
56
+ - A stable tag needs `docs/release-notes/vX.Y.Z.md` **in the tagged commit**.
57
+ Add it in the PR that will be tagged; adding it afterwards leaves the release
58
+ job failing on a tag that cannot be moved.
59
+ - Never reuse or move a published version. If a release is wrong, supersede it
60
+ with the next one and say so in its notes.
46
61
  - Before reporting completion, check the remote PR state and CI results with
47
62
  `gh pr view` / `gh pr checks`; report the actual status, not just that a
48
63
  branch was pushed.
@@ -112,17 +112,30 @@ repository settings that live outside git.
112
112
 
113
113
  ## Release Workflow
114
114
 
115
- Releases are built from tags in the form `vX.Y.Z`. Release PRs must include
116
- `docs/release-notes/vX.Y.Z.md`, copied from
117
- [docs/release-notes/TEMPLATE.md](docs/release-notes/TEMPLATE.md).
115
+ Two channels, described in full in [docs/release.md](docs/release.md).
118
116
 
119
- After the release PR has merged to `main`, verify the exact commit and then:
117
+ **Development channel.** Every commit that lands on the development branch with
118
+ green CI is published automatically as `X.Y.devN`. There is nothing to do and
119
+ nothing to decide: merging *is* releasing on this channel. Consume such a
120
+ version with an exact pin, which is how a downstream repository tracks work in
121
+ progress without reaching past the package boundary:
120
122
 
121
123
  ```bash
122
- git switch main
124
+ pipx install "rosotacom-dev==2.4.dev3"
125
+ ```
126
+
127
+ **Stable release.** Built from tags in the form `vX.Y.Z`. Release PRs must
128
+ include `docs/release-notes/vX.Y.Z.md`, copied from
129
+ [docs/release-notes/TEMPLATE.md](docs/release-notes/TEMPLATE.md) — the tagged
130
+ commit has to contain its own notes, so the notes land in the PR, not after it.
131
+
132
+ After the release PR has merged, verify the exact commit and then:
133
+
134
+ ```bash
135
+ git switch develop
123
136
  git fetch --prune
124
137
  git pull --ff-only
125
- git tag vX.Y.Z
138
+ git tag -a vX.Y.Z -m "rosotacom vX.Y.Z"
126
139
  git push origin vX.Y.Z
127
140
  ```
128
141
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rosotacom-dev
3
- Version: 2.2
3
+ Version: 2.4
4
4
  Summary: Host CLI for ROS OTA communication sessions.
5
5
  Author: develNor
6
6
  License-Expression: BSD-3-Clause
@@ -98,6 +98,9 @@ pipx install rosotacom-dev # isolated, on PATH everywhere
98
98
  on PyPI stays reserved for the FZI upstream. -->
99
99
  # or: pip install --user rosotacom
100
100
 
101
+ # a specific development build (for consumers tracking work in progress)
102
+ pipx install "rosotacom-dev==2.4.dev3"
103
+
101
104
  # from a source checkout (developers)
102
105
  cd /path/to/ros_communication_devcontainer
103
106
  ./install.sh # builds a checkout-local .venv
@@ -109,6 +112,12 @@ python -m rosotacom --version
109
112
  rosotacom doctor
110
113
  ```
111
114
 
115
+ Every commit that lands on the development branch with green CI is published as
116
+ a `X.Y.devN` pre-release, so a consumer never has to wait for a release decision
117
+ or reach past the package to a checkout. `pip` ignores pre-releases unless you
118
+ pin one exactly, so this cannot reach you by accident. See
119
+ [docs/release.md](docs/release.md).
120
+
112
121
  For a source checkout, that single `source .venv/bin/activate` command also
113
122
  enables completion. Nothing needs to be added to your shell configuration.
114
123
 
@@ -218,6 +227,23 @@ scripts/
218
227
  project-local directories first and shared/example directories later when one
219
228
  project should discover both.
220
229
 
230
+ ### Locating packaged resources
231
+
232
+ rosotacom is installed in an isolated environment (pipx, or a project venv), so
233
+ another tool cannot `import rosotacom` from a system Python to find the files
234
+ that ship with it. Ask the CLI instead — it prints one absolute path, so it
235
+ composes directly in a shell:
236
+
237
+ ```bash
238
+ rosotacom resources path com_msgs # the ROS 2 message package
239
+ rosotacom resources path ws # the packaged runtime workspace
240
+ ```
241
+
242
+ Use this wherever another project needs rosotacom's files on the host, for
243
+ example to bake `com_msgs` into its own container image. Ask for the resource by
244
+ name rather than reconstructing a path: the names are part of the CLI contract,
245
+ the layout behind them is not.
246
+
221
247
  See the [example project README](src/rosotacom/resources/examples/README.md)
222
248
  for the copyable example layout, the
223
249
  [session configuration reference](session-configuration.md) for the session
@@ -411,10 +437,10 @@ rosotacom ota-smoke 2_native_chatter \
411
437
  --peer b=robot
412
438
  ```
413
439
 
414
- `ota-smoke` accepts sessions and scenarios. It automatically stages and
415
- installs the currently selected rosotacom version, stages the active project,
416
- runs delivery and isolation checks, collects artifacts, stops the run, and
417
- removes the remote workdir. Add `--interactive` for a local control tmux with
440
+ `ota-smoke` accepts sessions and scenarios. It puts rosotacom on each peer,
441
+ stages the active project, runs delivery and isolation checks, collects
442
+ artifacts, stops the run, and removes the remote workdir. Add `--interactive`
443
+ for a local control tmux with
418
444
  one attachable communication/catmux window per peer with a live status pane below
419
445
  each one. Scenario targets also get one native application-container window per
420
446
  scenario app. Stop an interactive run with `rosotacom ota-smoke TARGET
@@ -423,6 +449,29 @@ metadata is not available. Use `--keep-running` to leave components up,
423
449
  `--keep-workdir` to retain staged files, or `--reuse` to reuse an existing
424
450
  installation.
425
451
 
452
+ #### What the peers run: `--install-mode`
453
+
454
+ ```bash
455
+ # default: stage and install what you are running, uncommitted changes included
456
+ rosotacom ota-smoke 2_native_chatter --peer a=workstation --peer b=robot
457
+
458
+ # rehearse a deployment: the peers install the published artefact
459
+ rosotacom ota-smoke 2_native_chatter --peer a=workstation --peer b=robot \
460
+ --install-mode pin # defaults to your own version
461
+ rosotacom ota-smoke 2_native_chatter --peer a=workstation --peer b=robot \
462
+ --install-mode pin --install-pin 2.4
463
+ ```
464
+
465
+ `source` is right while iterating on rosotacom itself — the peers run the code
466
+ in front of you. `pin` is right when the run is meant to stand in for a real
467
+ deployment: the peers install from the index, so a packaging defect (a file
468
+ missing from the wheel, an undeclared dependency) fails in the rehearsal instead
469
+ of on the target machine. `source` cannot catch that class of defect by
470
+ construction, because it never builds the artefact that ships.
471
+
472
+ The run manifest records which mode and which version the peers ran, so a result
473
+ can be attributed to an artefact rather than to a working copy.
474
+
426
475
  ### Live status / debugging overview
427
476
 
428
477
  Enable a continuously-updated, per-topic pipeline overview by setting
@@ -53,6 +53,9 @@ pipx install rosotacom-dev # isolated, on PATH everywhere
53
53
  on PyPI stays reserved for the FZI upstream. -->
54
54
  # or: pip install --user rosotacom
55
55
 
56
+ # a specific development build (for consumers tracking work in progress)
57
+ pipx install "rosotacom-dev==2.4.dev3"
58
+
56
59
  # from a source checkout (developers)
57
60
  cd /path/to/ros_communication_devcontainer
58
61
  ./install.sh # builds a checkout-local .venv
@@ -64,6 +67,12 @@ python -m rosotacom --version
64
67
  rosotacom doctor
65
68
  ```
66
69
 
70
+ Every commit that lands on the development branch with green CI is published as
71
+ a `X.Y.devN` pre-release, so a consumer never has to wait for a release decision
72
+ or reach past the package to a checkout. `pip` ignores pre-releases unless you
73
+ pin one exactly, so this cannot reach you by accident. See
74
+ [docs/release.md](docs/release.md).
75
+
67
76
  For a source checkout, that single `source .venv/bin/activate` command also
68
77
  enables completion. Nothing needs to be added to your shell configuration.
69
78
 
@@ -173,6 +182,23 @@ scripts/
173
182
  project-local directories first and shared/example directories later when one
174
183
  project should discover both.
175
184
 
185
+ ### Locating packaged resources
186
+
187
+ rosotacom is installed in an isolated environment (pipx, or a project venv), so
188
+ another tool cannot `import rosotacom` from a system Python to find the files
189
+ that ship with it. Ask the CLI instead — it prints one absolute path, so it
190
+ composes directly in a shell:
191
+
192
+ ```bash
193
+ rosotacom resources path com_msgs # the ROS 2 message package
194
+ rosotacom resources path ws # the packaged runtime workspace
195
+ ```
196
+
197
+ Use this wherever another project needs rosotacom's files on the host, for
198
+ example to bake `com_msgs` into its own container image. Ask for the resource by
199
+ name rather than reconstructing a path: the names are part of the CLI contract,
200
+ the layout behind them is not.
201
+
176
202
  See the [example project README](src/rosotacom/resources/examples/README.md)
177
203
  for the copyable example layout, the
178
204
  [session configuration reference](session-configuration.md) for the session
@@ -366,10 +392,10 @@ rosotacom ota-smoke 2_native_chatter \
366
392
  --peer b=robot
367
393
  ```
368
394
 
369
- `ota-smoke` accepts sessions and scenarios. It automatically stages and
370
- installs the currently selected rosotacom version, stages the active project,
371
- runs delivery and isolation checks, collects artifacts, stops the run, and
372
- removes the remote workdir. Add `--interactive` for a local control tmux with
395
+ `ota-smoke` accepts sessions and scenarios. It puts rosotacom on each peer,
396
+ stages the active project, runs delivery and isolation checks, collects
397
+ artifacts, stops the run, and removes the remote workdir. Add `--interactive`
398
+ for a local control tmux with
373
399
  one attachable communication/catmux window per peer with a live status pane below
374
400
  each one. Scenario targets also get one native application-container window per
375
401
  scenario app. Stop an interactive run with `rosotacom ota-smoke TARGET
@@ -378,6 +404,29 @@ metadata is not available. Use `--keep-running` to leave components up,
378
404
  `--keep-workdir` to retain staged files, or `--reuse` to reuse an existing
379
405
  installation.
380
406
 
407
+ #### What the peers run: `--install-mode`
408
+
409
+ ```bash
410
+ # default: stage and install what you are running, uncommitted changes included
411
+ rosotacom ota-smoke 2_native_chatter --peer a=workstation --peer b=robot
412
+
413
+ # rehearse a deployment: the peers install the published artefact
414
+ rosotacom ota-smoke 2_native_chatter --peer a=workstation --peer b=robot \
415
+ --install-mode pin # defaults to your own version
416
+ rosotacom ota-smoke 2_native_chatter --peer a=workstation --peer b=robot \
417
+ --install-mode pin --install-pin 2.4
418
+ ```
419
+
420
+ `source` is right while iterating on rosotacom itself — the peers run the code
421
+ in front of you. `pin` is right when the run is meant to stand in for a real
422
+ deployment: the peers install from the index, so a packaging defect (a file
423
+ missing from the wheel, an undeclared dependency) fails in the rehearsal instead
424
+ of on the target machine. `source` cannot catch that class of defect by
425
+ construction, because it never builds the artefact that ships.
426
+
427
+ The run manifest records which mode and which version the peers ran, so a result
428
+ can be attributed to an artefact rather than to a working copy.
429
+
381
430
  ### Live status / debugging overview
382
431
 
383
432
  Enable a continuously-updated, per-topic pipeline overview by setting
@@ -11,10 +11,14 @@ but one stable release line:
11
11
 
12
12
  - topic PRs are gated into the repository's active development branch by the
13
13
  GitHub checks below;
14
- - **`main`** is the stable release line;
14
+ - every commit that lands there with green CI is published as a `X.Y.devN`
15
+ pre-release, so any commit is consumable without a release decision;
16
+ - **`main`** is the stable line a repository synchronises upstream from;
15
17
  - moving development work to `main` is a deliberate maintainer operation and
16
18
  may require an external OTA gate;
17
- - releases are tags `vX.Y.Z` cut from `main` (see [release.md](release.md)).
19
+ - releases are tags `vX.Y.Z` cut from a validated commit on the release line —
20
+ in this repository `develop`, its default branch (see
21
+ [release.md](release.md)).
18
22
 
19
23
  The OTA tier is not part of this repository's public CI. An operator-supplied
20
24
  external runner provides it as a manual promotion gate, as described generically
@@ -0,0 +1,34 @@
1
+ # v2.3
2
+
3
+ ## Summary
4
+
5
+ - Add `rosotacom resources path <name>`: report the host path of a packaged
6
+ resource (`ws`, `com_msgs`) for tooling outside the installation. rosotacom
7
+ installs into an isolated environment (pipx, or a project venv), so a consumer
8
+ cannot `import rosotacom` to compute such a path; this command is the
9
+ supported lookup.
10
+
11
+ ## Compatibility And Migration
12
+
13
+ - No breaking changes. Consumers that hardcoded a path into a rosotacom checkout
14
+ should switch to `rosotacom resources path com_msgs`.
15
+
16
+ ## Known Issues
17
+
18
+ - An installed `rosotacom-dev` reports its version as `0+unknown`: the package
19
+ looked up the distribution name `rosotacom`, which the fork no longer uses.
20
+ A version check against a pin therefore never matches, and
21
+ `ota-smoke --install-mode source` started from an installation writes that
22
+ string into the source bundle it builds on each peer, where it is not a valid
23
+ PEP 440 version and the remote build fails. Fixed in 2.4; this release cannot
24
+ be replaced because a published version is immutable.
25
+
26
+ ## Validation
27
+
28
+ - `just lint`
29
+ - `just typecheck`
30
+ - `just test-unit`
31
+ - `just test-contract`
32
+ - `just docs`
33
+ - `just package`
34
+ - `just test-e2e-smoke`
@@ -0,0 +1,46 @@
1
+ # v2.4
2
+
3
+ ## Summary
4
+
5
+ - **Fix the reported version.** An installed distribution is now looked up
6
+ rather than assumed, so `rosotacom --version` reports the real version under
7
+ both published names (`rosotacom-dev` from this fork, `rosotacom` upstream).
8
+ Up to 2.3 every installed `rosotacom-dev` reported `0+unknown`, which made a
9
+ version check against a pin impossible and produced an unbuildable OTA source
10
+ bundle.
11
+ - **Publish a development channel.** Every commit that lands on the development
12
+ branch with green CI is published as a `X.Y.devN` pre-release. Consuming this
13
+ package no longer means waiting for a release decision. `pip` ignores
14
+ pre-releases unless one is pinned exactly, so the stable line is unaffected.
15
+ - **Stop duplicating packaging metadata.** The source bundle `ota-smoke` builds
16
+ when it runs from an installation derives its name, version, dependencies and
17
+ entry points from the installed distribution. The hand-written copy it used
18
+ before had drifted: `mcap` and `Pillow` were missing, so a peer prepared this
19
+ way imported fine and then failed inside the first MCAP or image code path.
20
+ - **`ota-smoke --install-mode pin`.** Install a published release on each peer
21
+ instead of staging a source tree, so the rehearsal runs the artefact that
22
+ ships and can catch a packaging defect before a target machine does. The run
23
+ manifest records the mode and version the peers ran.
24
+ - **`rosotacom resources path` covers `package` and `examples`**, which is how
25
+ pin mode remaps project config roots onto the peer's installation.
26
+
27
+ ## Compatibility And Migration
28
+
29
+ - `ota-smoke` behaves as before unless `--install-mode pin` is passed.
30
+ - The OTA deployment state file (`ota-deployment.yaml`) is now `schema_version:
31
+ 2` and carries the install mode. State files written by an older version are
32
+ rejected; they are per-run artifacts, so start a new run.
33
+ - Consumers pinning `rosotacom-dev==2.3` should move to `2.4` to get a usable
34
+ `--version`.
35
+
36
+ ## Validation
37
+
38
+ - `just lint`
39
+ - `just typecheck`
40
+ - `just test-unit`
41
+ - `just test-contract`
42
+ - `just docs`
43
+ - `just package`
44
+ - `just test-e2e-smoke`
45
+ - `tests/contract/test_ota_source_bundle.py` fails if the bundle metadata ever
46
+ diverges from `pyproject.toml` again.
@@ -0,0 +1,104 @@
1
+ # Release
2
+
3
+ This project publishes on two channels, and the difference between them is who
4
+ decides, not how much is tested. Both build from the same commit and the same
5
+ `just package`.
6
+
7
+ | | Development channel | Stable release |
8
+ |---|---|---|
9
+ | Trigger | every commit that lands on `develop` with green CI | a `vX.Y.Z` tag |
10
+ | Version | `X.Y.devN` (PEP 440 pre-release) | `X.Y.Z` |
11
+ | Built by | `.github/workflows/dev-release.yml` | `.github/workflows/release.yml` |
12
+ | Decided by | nobody — it follows the branch | a maintainer |
13
+ | Reached by | an exact pin, or `--pre` | a normal install |
14
+
15
+ The point of the development channel is that consuming this package should never
16
+ be more expensive than consuming a checkout. Downstream repositories pin an
17
+ exact version; without a continuous channel their only alternatives are to wait
18
+ for a release decision or to bypass the package boundary, and the second one
19
+ always wins in practice.
20
+
21
+ `pip` does not resolve pre-releases unless asked, so a dev version can never
22
+ reach a consumer by accident.
23
+
24
+ ## Version Source
25
+
26
+ Package versions come from Git tags through `setuptools-scm`. The project does
27
+ not keep a static version in `pyproject.toml` or `src/rosotacom/__init__.py`.
28
+
29
+ After `v2.3`, commits on `develop` therefore build as `2.4.devN`: a
30
+ pre-release *of the next* stable version, ordered before `2.4` itself.
31
+
32
+ The distribution name is never hardcoded in the source. This code publishes as
33
+ `rosotacom-dev` from the development fork and as `rosotacom` upstream, and
34
+ `rosotacom/__init__.py` looks its own distribution up rather than assuming a
35
+ name. Assuming one is what made every installed `rosotacom-dev` up to 2.3 report
36
+ its version as `0+unknown`.
37
+
38
+ The two "dev" in `rosotacom-dev==2.4.dev3` are not the same word, and only one
39
+ of them is about maturity:
40
+
41
+ - `-dev` in the **distribution name** says which line publishes it — the
42
+ development fork, as opposed to the FZI upstream that publishes as
43
+ `rosotacom`. It is part of every version of this package, stable ones
44
+ included: `rosotacom-dev==2.4` is a stable release.
45
+ - `.dev3` in the **version** says how far along that particular artefact is
46
+ within this line: the third commit after `v2.3`, on the way to `2.4`.
47
+
48
+ So `rosotacom-dev` alone tells you nothing about maturity. The version does.
49
+
50
+ ## Tags
51
+
52
+ Stable releases use tags in this form:
53
+
54
+ ```text
55
+ vX.Y.Z
56
+ ```
57
+
58
+ Tags are cut from a validated commit on the release line — in this repository
59
+ `develop`, which is also its default branch (see [ci.md](ci.md) for the branch
60
+ model). Before cutting one, a maintainer should record the manual full-suite
61
+ gate result described in [testing.md](testing.md). Push the tag from that exact
62
+ commit.
63
+
64
+ The tag build asserts that the version it produces is the version the tag names,
65
+ and the development channel asserts the mirror image: it refuses to publish
66
+ anything that is not a pre-release. Neither channel can publish under the
67
+ other's identity.
68
+
69
+ ## Release Notes
70
+
71
+ Each stable release must include:
72
+
73
+ ```text
74
+ docs/release-notes/vX.Y.Z.md
75
+ ```
76
+
77
+ Start from [docs/release-notes/TEMPLATE.md](release-notes/TEMPLATE.md). The
78
+ release notes should summarize user-facing CLI, config, packaging, Docker,
79
+ dependency, compatibility, and migration changes.
80
+
81
+ ## Publishing
82
+
83
+ Tag pushes validate, publish through the repository's configured Trusted
84
+ Publisher, and create a GitHub Release with the release notes, wheel, source
85
+ distribution, and `SHA256SUMS`. Manual workflow dispatch validates and builds
86
+ artifacts but does not publish; publishing a stable version requires a
87
+ deliberate `vX.Y.Z` tag.
88
+
89
+ Development-channel uploads use the same Trusted Publisher and the same
90
+ `PYPI_PUBLISH_URL`. They are triggered by the CI workflow *completing
91
+ successfully* on `develop`, not by the push itself, so a commit whose checks
92
+ failed is never published. They skip the TestPyPI rehearsal: the dev channel is
93
+ already the rehearsal.
94
+
95
+ The target index is set per repository by the `PYPI_PUBLISH_URL` Actions
96
+ variable, and authorization is granted by the Trusted Publisher registered for
97
+ that repository. Both controls live in repository settings rather than shared
98
+ git content.
99
+
100
+ Publishing a release does not authorize or trigger synchronization to another
101
+ repository. A downstream sync should use one stable tag as its boundary and
102
+ must separately verify the exact tag SHA, release notes, successful release
103
+ workflow, successful deployment, and generated artifacts before a PR is
104
+ created.